diff --git a/action.yml b/action.yml index 56a7538..16f4605 100644 --- a/action.yml +++ b/action.yml @@ -21,9 +21,24 @@ keywords: inputs: GITHUB_TOKEN: - description: 'GitHub token' + description: 'Token used for API calls (GitHub/Gitea/Forgejo). Typically set to ${{ secrets.GITHUB_TOKEN }}' required: true + DRY_RUN: + description: 'If true, the action will log proposed changes but will not rebase or push commits' + required: false + default: 'false' + + GIT_PLATFORM: + description: 'Platform the action is running on (e.g., "github", "gitea", "forgejo"). Determines API usage' + required: false + default: 'github' + + GIT_PLATFORM_API_BASE: + description: 'Base API URL for non-GitHub platforms (e.g., Gitea/Forgejo) for diff endpoints' + required: false + default: '' + runs: using: 'node16' main: 'out/github-action.cjs' diff --git a/out/github-action.cjs b/out/github-action.cjs index 39b526b..7d764e2 100644 --- a/out/github-action.cjs +++ b/out/github-action.cjs @@ -31,7 +31,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); -var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // node_modules/@actions/core/lib/utils.js var require_utils = __commonJS({ @@ -71,9 +70,13 @@ var require_command = __commonJS({ "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o3, m4, k4, k22) { if (k22 === void 0) k22 = k4; - Object.defineProperty(o3, k22, { enumerable: true, get: function() { - return m4[k4]; - } }); + var desc = Object.getOwnPropertyDescriptor(m4, k4); + if (!desc || ("get" in desc ? !m4.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m4[k4]; + } }; + } + Object.defineProperty(o3, k22, desc); } : function(o3, m4, k4, k22) { if (k22 === void 0) k22 = k4; o3[k22] = m4[k4]; @@ -87,7 +90,7 @@ var require_command = __commonJS({ if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) { - for (var k4 in mod) if (k4 !== "default" && Object.hasOwnProperty.call(mod, k4)) __createBinding(result, mod, k4); + for (var k4 in mod) if (k4 !== "default" && Object.prototype.hasOwnProperty.call(mod, k4)) __createBinding(result, mod, k4); } __setModuleDefault(result, mod); return result; @@ -139,356 +142,27 @@ var require_command = __commonJS({ } }; function escapeData(s2) { - return utils_1.toCommandValue(s2).replace(/%/g, "%25").replace(/\r/g, "%0D").replace(/\n/g, "%0A"); + return (0, utils_1.toCommandValue)(s2).replace(/%/g, "%25").replace(/\r/g, "%0D").replace(/\n/g, "%0A"); } function escapeProperty(s2) { - return utils_1.toCommandValue(s2).replace(/%/g, "%25").replace(/\r/g, "%0D").replace(/\n/g, "%0A").replace(/:/g, "%3A").replace(/,/g, "%2C"); + return (0, utils_1.toCommandValue)(s2).replace(/%/g, "%25").replace(/\r/g, "%0D").replace(/\n/g, "%0A").replace(/:/g, "%3A").replace(/,/g, "%2C"); } } }); -// node_modules/uuid/dist/esm-node/rng.js -function rng() { - if (poolPtr > rnds8Pool.length - 16) { - import_crypto.default.randomFillSync(rnds8Pool); - poolPtr = 0; - } - return rnds8Pool.slice(poolPtr, poolPtr += 16); -} -var import_crypto, rnds8Pool, poolPtr; -var init_rng = __esm({ - "node_modules/uuid/dist/esm-node/rng.js"() { - import_crypto = __toESM(require("crypto")); - rnds8Pool = new Uint8Array(256); - poolPtr = rnds8Pool.length; - } -}); - -// node_modules/uuid/dist/esm-node/regex.js -var regex_default; -var init_regex = __esm({ - "node_modules/uuid/dist/esm-node/regex.js"() { - regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; - } -}); - -// node_modules/uuid/dist/esm-node/validate.js -function validate(uuid) { - return typeof uuid === "string" && regex_default.test(uuid); -} -var validate_default; -var init_validate = __esm({ - "node_modules/uuid/dist/esm-node/validate.js"() { - init_regex(); - validate_default = validate; - } -}); - -// node_modules/uuid/dist/esm-node/stringify.js -function stringify(arr, offset = 0) { - const uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); - if (!validate_default(uuid)) { - throw TypeError("Stringified UUID is invalid"); - } - return uuid; -} -var byteToHex, stringify_default; -var init_stringify = __esm({ - "node_modules/uuid/dist/esm-node/stringify.js"() { - init_validate(); - byteToHex = []; - for (let i3 = 0; i3 < 256; ++i3) { - byteToHex.push((i3 + 256).toString(16).substr(1)); - } - stringify_default = stringify; - } -}); - -// node_modules/uuid/dist/esm-node/v1.js -function v1(options, buf, offset) { - let i3 = buf && offset || 0; - const b3 = buf || new Array(16); - options = options || {}; - let node = options.node || _nodeId; - let clockseq = options.clockseq !== void 0 ? options.clockseq : _clockseq; - if (node == null || clockseq == null) { - const seedBytes = options.random || (options.rng || rng)(); - if (node == null) { - node = _nodeId = [seedBytes[0] | 1, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; - } - if (clockseq == null) { - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 16383; - } - } - let msecs = options.msecs !== void 0 ? options.msecs : Date.now(); - let nsecs = options.nsecs !== void 0 ? options.nsecs : _lastNSecs + 1; - const dt2 = msecs - _lastMSecs + (nsecs - _lastNSecs) / 1e4; - if (dt2 < 0 && options.clockseq === void 0) { - clockseq = clockseq + 1 & 16383; - } - if ((dt2 < 0 || msecs > _lastMSecs) && options.nsecs === void 0) { - nsecs = 0; - } - if (nsecs >= 1e4) { - throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); - } - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; - msecs += 122192928e5; - const tl = ((msecs & 268435455) * 1e4 + nsecs) % 4294967296; - b3[i3++] = tl >>> 24 & 255; - b3[i3++] = tl >>> 16 & 255; - b3[i3++] = tl >>> 8 & 255; - b3[i3++] = tl & 255; - const tmh = msecs / 4294967296 * 1e4 & 268435455; - b3[i3++] = tmh >>> 8 & 255; - b3[i3++] = tmh & 255; - b3[i3++] = tmh >>> 24 & 15 | 16; - b3[i3++] = tmh >>> 16 & 255; - b3[i3++] = clockseq >>> 8 | 128; - b3[i3++] = clockseq & 255; - for (let n2 = 0; n2 < 6; ++n2) { - b3[i3 + n2] = node[n2]; - } - return buf || stringify_default(b3); -} -var _nodeId, _clockseq, _lastMSecs, _lastNSecs, v1_default; -var init_v1 = __esm({ - "node_modules/uuid/dist/esm-node/v1.js"() { - init_rng(); - init_stringify(); - _lastMSecs = 0; - _lastNSecs = 0; - v1_default = v1; - } -}); - -// node_modules/uuid/dist/esm-node/parse.js -function parse(uuid) { - if (!validate_default(uuid)) { - throw TypeError("Invalid UUID"); - } - let v2; - const arr = new Uint8Array(16); - arr[0] = (v2 = parseInt(uuid.slice(0, 8), 16)) >>> 24; - arr[1] = v2 >>> 16 & 255; - arr[2] = v2 >>> 8 & 255; - arr[3] = v2 & 255; - arr[4] = (v2 = parseInt(uuid.slice(9, 13), 16)) >>> 8; - arr[5] = v2 & 255; - arr[6] = (v2 = parseInt(uuid.slice(14, 18), 16)) >>> 8; - arr[7] = v2 & 255; - arr[8] = (v2 = parseInt(uuid.slice(19, 23), 16)) >>> 8; - arr[9] = v2 & 255; - arr[10] = (v2 = parseInt(uuid.slice(24, 36), 16)) / 1099511627776 & 255; - arr[11] = v2 / 4294967296 & 255; - arr[12] = v2 >>> 24 & 255; - arr[13] = v2 >>> 16 & 255; - arr[14] = v2 >>> 8 & 255; - arr[15] = v2 & 255; - return arr; -} -var parse_default; -var init_parse = __esm({ - "node_modules/uuid/dist/esm-node/parse.js"() { - init_validate(); - parse_default = parse; - } -}); - -// node_modules/uuid/dist/esm-node/v35.js -function stringToBytes(str2) { - str2 = unescape(encodeURIComponent(str2)); - const bytes = []; - for (let i3 = 0; i3 < str2.length; ++i3) { - bytes.push(str2.charCodeAt(i3)); - } - return bytes; -} -function v35_default(name, version2, hashfunc) { - function generateUUID(value, namespace, buf, offset) { - if (typeof value === "string") { - value = stringToBytes(value); - } - if (typeof namespace === "string") { - namespace = parse_default(namespace); - } - if (namespace.length !== 16) { - throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)"); - } - let bytes = new Uint8Array(16 + value.length); - bytes.set(namespace); - bytes.set(value, namespace.length); - bytes = hashfunc(bytes); - bytes[6] = bytes[6] & 15 | version2; - bytes[8] = bytes[8] & 63 | 128; - if (buf) { - offset = offset || 0; - for (let i3 = 0; i3 < 16; ++i3) { - buf[offset + i3] = bytes[i3]; - } - return buf; - } - return stringify_default(bytes); - } - try { - generateUUID.name = name; - } catch (err) { - } - generateUUID.DNS = DNS; - generateUUID.URL = URL2; - return generateUUID; -} -var DNS, URL2; -var init_v35 = __esm({ - "node_modules/uuid/dist/esm-node/v35.js"() { - init_stringify(); - init_parse(); - DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; - URL2 = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"; - } -}); - -// node_modules/uuid/dist/esm-node/md5.js -function md5(bytes) { - if (Array.isArray(bytes)) { - bytes = Buffer.from(bytes); - } else if (typeof bytes === "string") { - bytes = Buffer.from(bytes, "utf8"); - } - return import_crypto2.default.createHash("md5").update(bytes).digest(); -} -var import_crypto2, md5_default; -var init_md5 = __esm({ - "node_modules/uuid/dist/esm-node/md5.js"() { - import_crypto2 = __toESM(require("crypto")); - md5_default = md5; - } -}); - -// node_modules/uuid/dist/esm-node/v3.js -var v3, v3_default; -var init_v3 = __esm({ - "node_modules/uuid/dist/esm-node/v3.js"() { - init_v35(); - init_md5(); - v3 = v35_default("v3", 48, md5_default); - v3_default = v3; - } -}); - -// node_modules/uuid/dist/esm-node/v4.js -function v4(options, buf, offset) { - options = options || {}; - const rnds = options.random || (options.rng || rng)(); - rnds[6] = rnds[6] & 15 | 64; - rnds[8] = rnds[8] & 63 | 128; - if (buf) { - offset = offset || 0; - for (let i3 = 0; i3 < 16; ++i3) { - buf[offset + i3] = rnds[i3]; - } - return buf; - } - return stringify_default(rnds); -} -var v4_default; -var init_v4 = __esm({ - "node_modules/uuid/dist/esm-node/v4.js"() { - init_rng(); - init_stringify(); - v4_default = v4; - } -}); - -// node_modules/uuid/dist/esm-node/sha1.js -function sha1(bytes) { - if (Array.isArray(bytes)) { - bytes = Buffer.from(bytes); - } else if (typeof bytes === "string") { - bytes = Buffer.from(bytes, "utf8"); - } - return import_crypto3.default.createHash("sha1").update(bytes).digest(); -} -var import_crypto3, sha1_default; -var init_sha1 = __esm({ - "node_modules/uuid/dist/esm-node/sha1.js"() { - import_crypto3 = __toESM(require("crypto")); - sha1_default = sha1; - } -}); - -// node_modules/uuid/dist/esm-node/v5.js -var v5, v5_default; -var init_v5 = __esm({ - "node_modules/uuid/dist/esm-node/v5.js"() { - init_v35(); - init_sha1(); - v5 = v35_default("v5", 80, sha1_default); - v5_default = v5; - } -}); - -// node_modules/uuid/dist/esm-node/nil.js -var nil_default; -var init_nil = __esm({ - "node_modules/uuid/dist/esm-node/nil.js"() { - nil_default = "00000000-0000-0000-0000-000000000000"; - } -}); - -// node_modules/uuid/dist/esm-node/version.js -function version(uuid) { - if (!validate_default(uuid)) { - throw TypeError("Invalid UUID"); - } - return parseInt(uuid.substr(14, 1), 16); -} -var version_default; -var init_version = __esm({ - "node_modules/uuid/dist/esm-node/version.js"() { - init_validate(); - version_default = version; - } -}); - -// node_modules/uuid/dist/esm-node/index.js -var esm_node_exports = {}; -__export(esm_node_exports, { - NIL: () => nil_default, - parse: () => parse_default, - stringify: () => stringify_default, - v1: () => v1_default, - v3: () => v3_default, - v4: () => v4_default, - v5: () => v5_default, - validate: () => validate_default, - version: () => version_default -}); -var init_esm_node = __esm({ - "node_modules/uuid/dist/esm-node/index.js"() { - init_v1(); - init_v3(); - init_v4(); - init_v5(); - init_nil(); - init_version(); - init_validate(); - init_stringify(); - init_parse(); - } -}); - // node_modules/@actions/core/lib/file-command.js var require_file_command = __commonJS({ "node_modules/@actions/core/lib/file-command.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o3, m4, k4, k22) { if (k22 === void 0) k22 = k4; - Object.defineProperty(o3, k22, { enumerable: true, get: function() { - return m4[k4]; - } }); + var desc = Object.getOwnPropertyDescriptor(m4, k4); + if (!desc || ("get" in desc ? !m4.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m4[k4]; + } }; + } + Object.defineProperty(o3, k22, desc); } : function(o3, m4, k4, k22) { if (k22 === void 0) k22 = k4; o3[k22] = m4[k4]; @@ -502,16 +176,16 @@ var require_file_command = __commonJS({ if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) { - for (var k4 in mod) if (k4 !== "default" && Object.hasOwnProperty.call(mod, k4)) __createBinding(result, mod, k4); + for (var k4 in mod) if (k4 !== "default" && Object.prototype.hasOwnProperty.call(mod, k4)) __createBinding(result, mod, k4); } __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.prepareKeyValueMessage = exports2.issueFileCommand = void 0; + var crypto3 = __importStar(require("crypto")); var fs4 = __importStar(require("fs")); var os3 = __importStar(require("os")); - var uuid_1 = (init_esm_node(), __toCommonJS(esm_node_exports)); var utils_1 = require_utils(); function issueFileCommand(command, message) { const filePath = process.env[`GITHUB_${command}`]; @@ -521,14 +195,14 @@ var require_file_command = __commonJS({ if (!fs4.existsSync(filePath)) { throw new Error(`Missing file at path: ${filePath}`); } - fs4.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os3.EOL}`, { + fs4.appendFileSync(filePath, `${(0, utils_1.toCommandValue)(message)}${os3.EOL}`, { encoding: "utf8" }); } exports2.issueFileCommand = issueFileCommand; function prepareKeyValueMessage(key, value) { - const delimiter = `ghadelimiter_${uuid_1.v4()}`; - const convertedValue = utils_1.toCommandValue(value); + const delimiter = `ghadelimiter_${crypto3.randomUUID()}`; + const convertedValue = (0, utils_1.toCommandValue)(value); if (key.includes(delimiter)) { throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); } @@ -1258,7 +932,7 @@ var require_util = __commonJS({ var { InvalidArgumentError } = require_errors(); var { Blob: Blob5 } = require("buffer"); var nodeUtil = require("util"); - var { stringify: stringify3 } = require("querystring"); + var { stringify: stringify2 } = require("querystring"); var { headerNameLowerCasedRecord } = require_constants(); var [nodeMajor, nodeMinor] = process.versions.node.split(".").map((v2) => Number(v2)); function nop() { @@ -1273,7 +947,7 @@ var require_util = __commonJS({ if (url2.includes("?") || url2.includes("#")) { throw new Error('Query params cannot be passed when url already contains "?" or "#".'); } - const stringified = stringify3(queryParams); + const stringified = stringify2(queryParams); if (stringified) { url2 += "?" + stringified; } @@ -3949,11 +3623,11 @@ var require_util2 = __commonJS({ var assert = require("assert"); var { isUint8Array } = require("util/types"); var supportedHashes = []; - var crypto6; + var crypto3; try { - crypto6 = require("crypto"); + crypto3 = require("crypto"); const possibleRelevantHashes = ["sha256", "sha384", "sha512"]; - supportedHashes = crypto6.getHashes().filter((hash) => possibleRelevantHashes.includes(hash)); + supportedHashes = crypto3.getHashes().filter((hash) => possibleRelevantHashes.includes(hash)); } catch { } function responseURL(response) { @@ -4230,7 +3904,7 @@ var require_util2 = __commonJS({ } } function bytesMatch(bytes, metadataList) { - if (crypto6 === void 0) { + if (crypto3 === void 0) { return true; } const parsedMetadata = parseMetadata(metadataList); @@ -4245,7 +3919,7 @@ var require_util2 = __commonJS({ for (const item of metadata) { const algorithm = item.algo; const expectedValue = item.hash; - let actualValue = crypto6.createHash(algorithm).update(bytes).digest("base64"); + let actualValue = crypto3.createHash(algorithm).update(bytes).digest("base64"); if (actualValue[actualValue.length - 1] === "=") { if (actualValue[actualValue.length - 2] === "=") { actualValue = actualValue.slice(0, -2); @@ -5591,8 +5265,8 @@ var require_body = __commonJS({ var { parseMIMEType, serializeAMimeType } = require_dataURL(); var random; try { - const crypto6 = require("node:crypto"); - random = (max) => crypto6.randomInt(0, max); + const crypto3 = require("node:crypto"); + random = (max) => crypto3.randomInt(0, max); } catch { random = (max) => Math.floor(Math.random(max)); } @@ -11382,7 +11056,7 @@ var require_proxy_agent = __commonJS({ "node_modules/undici/lib/proxy-agent.js"(exports2, module2) { "use strict"; var { kProxy, kClose, kDestroy, kInterceptors } = require_symbols(); - var { URL: URL3 } = require("url"); + var { URL: URL2 } = require("url"); var Agent3 = require_agent(); var Pool = require_pool(); var DispatcherBase = require_dispatcher_base(); @@ -11431,7 +11105,7 @@ var require_proxy_agent = __commonJS({ this[kRequestTls] = opts.requestTls; this[kProxyTls] = opts.proxyTls; this[kProxyHeaders] = opts.headers || {}; - const resolvedUrl = new URL3(opts.uri); + const resolvedUrl = new URL2(opts.uri); const { origin: origin2, port, host, username, password } = resolvedUrl; if (opts.auth && opts.token) { throw new InvalidArgumentError("opts.auth cannot be used in combination with opts.token"); @@ -11486,7 +11160,7 @@ var require_proxy_agent = __commonJS({ }); } dispatch(opts, handler) { - const { host } = new URL3(opts.origin); + const { host } = new URL2(opts.origin); const headers = buildHeaders(opts.headers); throwIfProxyAuthIsSent(headers); return this[kAgent].dispatch( @@ -13366,7 +13040,7 @@ var require_fetch = __commonJS({ this.emit("terminated", error); } }; - function fetch4(input, init = {}) { + function fetch5(input, init = {}) { webidl.argumentLengthCheck(arguments, 1, { header: "globalThis.fetch" }); const p3 = createDeferredPromise(); let requestObject; @@ -14296,7 +13970,7 @@ var require_fetch = __commonJS({ } } module2.exports = { - fetch: fetch4, + fetch: fetch5, Fetch, fetching, finalizeAndReportTiming @@ -15898,7 +15572,7 @@ var require_util6 = __commonJS({ throw new Error("Invalid cookie max-age"); } } - function stringify3(cookie) { + function stringify2(cookie) { if (cookie.name.length === 0) { return null; } @@ -15952,7 +15626,7 @@ var require_util6 = __commonJS({ validateCookiePath, validateCookieValue, toIMFDate, - stringify: stringify3 + stringify: stringify2 }; } }); @@ -16102,7 +15776,7 @@ var require_cookies = __commonJS({ "node_modules/undici/lib/cookies/index.js"(exports2, module2) { "use strict"; var { parseSetCookie } = require_parse(); - var { stringify: stringify3 } = require_util6(); + var { stringify: stringify2 } = require_util6(); var { webidl } = require_webidl(); var { Headers: Headers6 } = require_headers(); function getCookies(headers) { @@ -16144,9 +15818,9 @@ var require_cookies = __commonJS({ webidl.argumentLengthCheck(arguments, 2, { header: "setCookie" }); webidl.brandCheck(headers, Headers6, { strict: false }); cookie = webidl.converters.Cookie(cookie); - const str2 = stringify3(cookie); + const str2 = stringify2(cookie); if (str2) { - headers.append("Set-Cookie", stringify3(cookie)); + headers.append("Set-Cookie", stringify2(cookie)); } } webidl.converters.DeleteCookieAttributes = webidl.dictionaryConverter([ @@ -16642,9 +16316,9 @@ var require_connection = __commonJS({ channels.open = diagnosticsChannel.channel("undici:websocket:open"); channels.close = diagnosticsChannel.channel("undici:websocket:close"); channels.socketError = diagnosticsChannel.channel("undici:websocket:socket_error"); - var crypto6; + var crypto3; try { - crypto6 = require("crypto"); + crypto3 = require("crypto"); } catch { } function establishWebSocketConnection(url2, protocols, ws, onEstablish, options) { @@ -16663,7 +16337,7 @@ var require_connection = __commonJS({ const headersList = new Headers6(options.headers)[kHeadersList]; request3.headersList = headersList; } - const keyValue = crypto6.randomBytes(16).toString("base64"); + const keyValue = crypto3.randomBytes(16).toString("base64"); request3.headersList.append("sec-websocket-key", keyValue); request3.headersList.append("sec-websocket-version", "13"); for (const protocol of protocols) { @@ -16692,7 +16366,7 @@ var require_connection = __commonJS({ return; } const secWSAccept = response.headersList.get("Sec-WebSocket-Accept"); - const digest = crypto6.createHash("sha1").update(keyValue + uid).digest("base64"); + const digest = crypto3.createHash("sha1").update(keyValue + uid).digest("base64"); if (secWSAccept !== digest) { failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header."); return; @@ -16772,9 +16446,9 @@ var require_frame = __commonJS({ "node_modules/undici/lib/websocket/frame.js"(exports2, module2) { "use strict"; var { maxUnsigned16Bit } = require_constants5(); - var crypto6; + var crypto3; try { - crypto6 = require("crypto"); + crypto3 = require("crypto"); } catch { } var WebsocketFrameSend = class { @@ -16783,7 +16457,7 @@ var require_frame = __commonJS({ */ constructor(data) { this.frameData = data; - this.maskKey = crypto6.randomBytes(4); + this.maskKey = crypto3.randomBytes(4); } createFrame(opcode) { const bodyLength = this.frameData?.byteLength ?? 0; @@ -17552,7 +17226,7 @@ var require_undici = __commonJS({ module2.exports.getGlobalDispatcher = getGlobalDispatcher; if (util4.nodeMajor > 16 || util4.nodeMajor === 16 && util4.nodeMinor >= 8) { let fetchImpl = null; - module2.exports.fetch = async function fetch4(resource) { + module2.exports.fetch = async function fetch5(resource) { if (!fetchImpl) { fetchImpl = require_fetch().fetch; } @@ -18411,9 +18085,9 @@ var require_oidc_utils = __commonJS({ const encodedAudience = encodeURIComponent(audience); id_token_url = `${id_token_url}&audience=${encodedAudience}`; } - core_1.debug(`ID token url is ${id_token_url}`); + (0, core_1.debug)(`ID token url is ${id_token_url}`); const id_token = yield _OidcClient.getCall(id_token_url); - core_1.setSecret(id_token); + (0, core_1.setSecret)(id_token); return id_token; } catch (error) { throw new Error(`Error message: ${error.message}`); @@ -18725,9 +18399,13 @@ var require_path_utils = __commonJS({ "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o3, m4, k4, k22) { if (k22 === void 0) k22 = k4; - Object.defineProperty(o3, k22, { enumerable: true, get: function() { - return m4[k4]; - } }); + var desc = Object.getOwnPropertyDescriptor(m4, k4); + if (!desc || ("get" in desc ? !m4.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m4[k4]; + } }; + } + Object.defineProperty(o3, k22, desc); } : function(o3, m4, k4, k22) { if (k22 === void 0) k22 = k4; o3[k22] = m4[k4]; @@ -18741,7 +18419,7 @@ var require_path_utils = __commonJS({ if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) { - for (var k4 in mod) if (k4 !== "default" && Object.hasOwnProperty.call(mod, k4)) __createBinding(result, mod, k4); + for (var k4 in mod) if (k4 !== "default" && Object.prototype.hasOwnProperty.call(mod, k4)) __createBinding(result, mod, k4); } __setModuleDefault(result, mod); return result; @@ -18764,230 +18442,6 @@ var require_path_utils = __commonJS({ } }); -// node_modules/@actions/core/lib/core.js -var require_core = __commonJS({ - "node_modules/@actions/core/lib/core.js"(exports2) { - "use strict"; - var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o3, m4, k4, k22) { - if (k22 === void 0) k22 = k4; - Object.defineProperty(o3, k22, { enumerable: true, get: function() { - return m4[k4]; - } }); - } : function(o3, m4, k4, k22) { - if (k22 === void 0) k22 = k4; - o3[k22] = m4[k4]; - }); - var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o3, v2) { - Object.defineProperty(o3, "default", { enumerable: true, value: v2 }); - } : function(o3, v2) { - o3["default"] = v2; - }); - var __importStar = exports2 && exports2.__importStar || function(mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) { - for (var k4 in mod) if (k4 !== "default" && Object.hasOwnProperty.call(mod, k4)) __createBinding(result, mod, k4); - } - __setModuleDefault(result, mod); - return result; - }; - var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P3, generator) { - function adopt(value) { - return value instanceof P3 ? value : new P3(function(resolve) { - resolve(value); - }); - } - return new (P3 || (P3 = Promise))(function(resolve, reject) { - function fulfilled(value) { - try { - step(generator.next(value)); - } catch (e3) { - reject(e3); - } - } - function rejected(value) { - try { - step(generator["throw"](value)); - } catch (e3) { - reject(e3); - } - } - function step(result) { - result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); - } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); - }; - Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.getIDToken = exports2.getState = exports2.saveState = exports2.group = exports2.endGroup = exports2.startGroup = exports2.info = exports2.notice = exports2.warning = exports2.error = exports2.debug = exports2.isDebug = exports2.setFailed = exports2.setCommandEcho = exports2.setOutput = exports2.getBooleanInput = exports2.getMultilineInput = exports2.getInput = exports2.addPath = exports2.setSecret = exports2.exportVariable = exports2.ExitCode = void 0; - var command_1 = require_command(); - var file_command_1 = require_file_command(); - var utils_1 = require_utils(); - var os3 = __importStar(require("os")); - var path2 = __importStar(require("path")); - var oidc_utils_1 = require_oidc_utils(); - var ExitCode; - (function(ExitCode2) { - ExitCode2[ExitCode2["Success"] = 0] = "Success"; - ExitCode2[ExitCode2["Failure"] = 1] = "Failure"; - })(ExitCode = exports2.ExitCode || (exports2.ExitCode = {})); - function exportVariable(name, val) { - const convertedVal = utils_1.toCommandValue(val); - process.env[name] = convertedVal; - const filePath = process.env["GITHUB_ENV"] || ""; - if (filePath) { - return file_command_1.issueFileCommand("ENV", file_command_1.prepareKeyValueMessage(name, val)); - } - command_1.issueCommand("set-env", { name }, convertedVal); - } - exports2.exportVariable = exportVariable; - function setSecret(secret) { - command_1.issueCommand("add-mask", {}, secret); - } - exports2.setSecret = setSecret; - function addPath(inputPath) { - const filePath = process.env["GITHUB_PATH"] || ""; - if (filePath) { - file_command_1.issueFileCommand("PATH", inputPath); - } else { - command_1.issueCommand("add-path", {}, inputPath); - } - process.env["PATH"] = `${inputPath}${path2.delimiter}${process.env["PATH"]}`; - } - exports2.addPath = addPath; - function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(/ /g, "_").toUpperCase()}`] || ""; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); - } - if (options && options.trimWhitespace === false) { - return val; - } - return val.trim(); - } - exports2.getInput = getInput; - function getMultilineInput(name, options) { - const inputs = getInput(name, options).split("\n").filter((x2) => x2 !== ""); - if (options && options.trimWhitespace === false) { - return inputs; - } - return inputs.map((input) => input.trim()); - } - exports2.getMultilineInput = getMultilineInput; - function getBooleanInput(name, options) { - const trueValue = ["true", "True", "TRUE"]; - const falseValue = ["false", "False", "FALSE"]; - const val = getInput(name, options); - if (trueValue.includes(val)) - return true; - if (falseValue.includes(val)) - return false; - throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name} -Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); - } - exports2.getBooleanInput = getBooleanInput; - function setOutput(name, value) { - const filePath = process.env["GITHUB_OUTPUT"] || ""; - if (filePath) { - return file_command_1.issueFileCommand("OUTPUT", file_command_1.prepareKeyValueMessage(name, value)); - } - process.stdout.write(os3.EOL); - command_1.issueCommand("set-output", { name }, utils_1.toCommandValue(value)); - } - exports2.setOutput = setOutput; - function setCommandEcho(enabled2) { - command_1.issue("echo", enabled2 ? "on" : "off"); - } - exports2.setCommandEcho = setCommandEcho; - function setFailed(message) { - process.exitCode = ExitCode.Failure; - error(message); - } - exports2.setFailed = setFailed; - function isDebug() { - return process.env["RUNNER_DEBUG"] === "1"; - } - exports2.isDebug = isDebug; - function debug3(message) { - command_1.issueCommand("debug", {}, message); - } - exports2.debug = debug3; - function error(message, properties = {}) { - command_1.issueCommand("error", utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); - } - exports2.error = error; - function warning(message, properties = {}) { - command_1.issueCommand("warning", utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); - } - exports2.warning = warning; - function notice(message, properties = {}) { - command_1.issueCommand("notice", utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); - } - exports2.notice = notice; - function info(message) { - process.stdout.write(message + os3.EOL); - } - exports2.info = info; - function startGroup(name) { - command_1.issue("group", name); - } - exports2.startGroup = startGroup; - function endGroup() { - command_1.issue("endgroup"); - } - exports2.endGroup = endGroup; - function group(name, fn) { - return __awaiter(this, void 0, void 0, function* () { - startGroup(name); - let result; - try { - result = yield fn(); - } finally { - endGroup(); - } - return result; - }); - } - exports2.group = group; - function saveState(name, value) { - const filePath = process.env["GITHUB_STATE"] || ""; - if (filePath) { - return file_command_1.issueFileCommand("STATE", file_command_1.prepareKeyValueMessage(name, value)); - } - command_1.issueCommand("save-state", { name }, utils_1.toCommandValue(value)); - } - exports2.saveState = saveState; - function getState(name) { - return process.env[`STATE_${name}`] || ""; - } - exports2.getState = getState; - function getIDToken(aud) { - return __awaiter(this, void 0, void 0, function* () { - return yield oidc_utils_1.OidcClient.getIDToken(aud); - }); - } - exports2.getIDToken = getIDToken; - var summary_1 = require_summary(); - Object.defineProperty(exports2, "summary", { enumerable: true, get: function() { - return summary_1.summary; - } }); - var summary_2 = require_summary(); - Object.defineProperty(exports2, "markdownSummary", { enumerable: true, get: function() { - return summary_2.markdownSummary; - } }); - var path_utils_1 = require_path_utils(); - Object.defineProperty(exports2, "toPosixPath", { enumerable: true, get: function() { - return path_utils_1.toPosixPath; - } }); - Object.defineProperty(exports2, "toWin32Path", { enumerable: true, get: function() { - return path_utils_1.toWin32Path; - } }); - Object.defineProperty(exports2, "toPlatformPath", { enumerable: true, get: function() { - return path_utils_1.toPlatformPath; - } }); - } -}); - // node_modules/@actions/io/lib/io-util.js var require_io_util = __commonJS({ "node_modules/@actions/io/lib/io-util.js"(exports2) { @@ -20000,6 +19454,354 @@ var require_exec = __commonJS({ } }); +// node_modules/@actions/core/lib/platform.js +var require_platform = __commonJS({ + "node_modules/@actions/core/lib/platform.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o3, m4, k4, k22) { + if (k22 === void 0) k22 = k4; + var desc = Object.getOwnPropertyDescriptor(m4, k4); + if (!desc || ("get" in desc ? !m4.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m4[k4]; + } }; + } + Object.defineProperty(o3, k22, desc); + } : function(o3, m4, k4, k22) { + if (k22 === void 0) k22 = k4; + o3[k22] = m4[k4]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o3, v2) { + Object.defineProperty(o3, "default", { enumerable: true, value: v2 }); + } : function(o3, v2) { + o3["default"] = v2; + }); + var __importStar = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k4 in mod) if (k4 !== "default" && Object.prototype.hasOwnProperty.call(mod, k4)) __createBinding(result, mod, k4); + } + __setModuleDefault(result, mod); + return result; + }; + var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P3, generator) { + function adopt(value) { + return value instanceof P3 ? value : new P3(function(resolve) { + resolve(value); + }); + } + return new (P3 || (P3 = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e3) { + reject(e3); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e3) { + reject(e3); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var __importDefault = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.getDetails = exports2.isLinux = exports2.isMacOS = exports2.isWindows = exports2.arch = exports2.platform = void 0; + var os_1 = __importDefault(require("os")); + var exec2 = __importStar(require_exec()); + var getWindowsInfo = () => __awaiter(void 0, void 0, void 0, function* () { + const { stdout: version } = yield exec2.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', void 0, { + silent: true + }); + const { stdout: name } = yield exec2.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Caption"', void 0, { + silent: true + }); + return { + name: name.trim(), + version: version.trim() + }; + }); + var getMacOsInfo = () => __awaiter(void 0, void 0, void 0, function* () { + var _a5, _b2, _c2, _d2; + const { stdout } = yield exec2.getExecOutput("sw_vers", void 0, { + silent: true + }); + const version = (_b2 = (_a5 = stdout.match(/ProductVersion:\s*(.+)/)) === null || _a5 === void 0 ? void 0 : _a5[1]) !== null && _b2 !== void 0 ? _b2 : ""; + const name = (_d2 = (_c2 = stdout.match(/ProductName:\s*(.+)/)) === null || _c2 === void 0 ? void 0 : _c2[1]) !== null && _d2 !== void 0 ? _d2 : ""; + return { + name, + version + }; + }); + var getLinuxInfo = () => __awaiter(void 0, void 0, void 0, function* () { + const { stdout } = yield exec2.getExecOutput("lsb_release", ["-i", "-r", "-s"], { + silent: true + }); + const [name, version] = stdout.trim().split("\n"); + return { + name, + version + }; + }); + exports2.platform = os_1.default.platform(); + exports2.arch = os_1.default.arch(); + exports2.isWindows = exports2.platform === "win32"; + exports2.isMacOS = exports2.platform === "darwin"; + exports2.isLinux = exports2.platform === "linux"; + function getDetails() { + return __awaiter(this, void 0, void 0, function* () { + return Object.assign(Object.assign({}, yield exports2.isWindows ? getWindowsInfo() : exports2.isMacOS ? getMacOsInfo() : getLinuxInfo()), { + platform: exports2.platform, + arch: exports2.arch, + isWindows: exports2.isWindows, + isMacOS: exports2.isMacOS, + isLinux: exports2.isLinux + }); + }); + } + exports2.getDetails = getDetails; + } +}); + +// node_modules/@actions/core/lib/core.js +var require_core = __commonJS({ + "node_modules/@actions/core/lib/core.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o3, m4, k4, k22) { + if (k22 === void 0) k22 = k4; + var desc = Object.getOwnPropertyDescriptor(m4, k4); + if (!desc || ("get" in desc ? !m4.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m4[k4]; + } }; + } + Object.defineProperty(o3, k22, desc); + } : function(o3, m4, k4, k22) { + if (k22 === void 0) k22 = k4; + o3[k22] = m4[k4]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o3, v2) { + Object.defineProperty(o3, "default", { enumerable: true, value: v2 }); + } : function(o3, v2) { + o3["default"] = v2; + }); + var __importStar = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k4 in mod) if (k4 !== "default" && Object.prototype.hasOwnProperty.call(mod, k4)) __createBinding(result, mod, k4); + } + __setModuleDefault(result, mod); + return result; + }; + var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P3, generator) { + function adopt(value) { + return value instanceof P3 ? value : new P3(function(resolve) { + resolve(value); + }); + } + return new (P3 || (P3 = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e3) { + reject(e3); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e3) { + reject(e3); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.platform = exports2.toPlatformPath = exports2.toWin32Path = exports2.toPosixPath = exports2.markdownSummary = exports2.summary = exports2.getIDToken = exports2.getState = exports2.saveState = exports2.group = exports2.endGroup = exports2.startGroup = exports2.info = exports2.notice = exports2.warning = exports2.error = exports2.debug = exports2.isDebug = exports2.setFailed = exports2.setCommandEcho = exports2.setOutput = exports2.getBooleanInput = exports2.getMultilineInput = exports2.getInput = exports2.addPath = exports2.setSecret = exports2.exportVariable = exports2.ExitCode = void 0; + var command_1 = require_command(); + var file_command_1 = require_file_command(); + var utils_1 = require_utils(); + var os3 = __importStar(require("os")); + var path2 = __importStar(require("path")); + var oidc_utils_1 = require_oidc_utils(); + var ExitCode; + (function(ExitCode2) { + ExitCode2[ExitCode2["Success"] = 0] = "Success"; + ExitCode2[ExitCode2["Failure"] = 1] = "Failure"; + })(ExitCode || (exports2.ExitCode = ExitCode = {})); + function exportVariable(name, val) { + const convertedVal = (0, utils_1.toCommandValue)(val); + process.env[name] = convertedVal; + const filePath = process.env["GITHUB_ENV"] || ""; + if (filePath) { + return (0, file_command_1.issueFileCommand)("ENV", (0, file_command_1.prepareKeyValueMessage)(name, val)); + } + (0, command_1.issueCommand)("set-env", { name }, convertedVal); + } + exports2.exportVariable = exportVariable; + function setSecret(secret) { + (0, command_1.issueCommand)("add-mask", {}, secret); + } + exports2.setSecret = setSecret; + function addPath(inputPath) { + const filePath = process.env["GITHUB_PATH"] || ""; + if (filePath) { + (0, file_command_1.issueFileCommand)("PATH", inputPath); + } else { + (0, command_1.issueCommand)("add-path", {}, inputPath); + } + process.env["PATH"] = `${inputPath}${path2.delimiter}${process.env["PATH"]}`; + } + exports2.addPath = addPath; + function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, "_").toUpperCase()}`] || ""; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); + } + if (options && options.trimWhitespace === false) { + return val; + } + return val.trim(); + } + exports2.getInput = getInput; + function getMultilineInput(name, options) { + const inputs = getInput(name, options).split("\n").filter((x2) => x2 !== ""); + if (options && options.trimWhitespace === false) { + return inputs; + } + return inputs.map((input) => input.trim()); + } + exports2.getMultilineInput = getMultilineInput; + function getBooleanInput(name, options) { + const trueValue = ["true", "True", "TRUE"]; + const falseValue = ["false", "False", "FALSE"]; + const val = getInput(name, options); + if (trueValue.includes(val)) + return true; + if (falseValue.includes(val)) + return false; + throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name} +Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); + } + exports2.getBooleanInput = getBooleanInput; + function setOutput(name, value) { + const filePath = process.env["GITHUB_OUTPUT"] || ""; + if (filePath) { + return (0, file_command_1.issueFileCommand)("OUTPUT", (0, file_command_1.prepareKeyValueMessage)(name, value)); + } + process.stdout.write(os3.EOL); + (0, command_1.issueCommand)("set-output", { name }, (0, utils_1.toCommandValue)(value)); + } + exports2.setOutput = setOutput; + function setCommandEcho(enabled2) { + (0, command_1.issue)("echo", enabled2 ? "on" : "off"); + } + exports2.setCommandEcho = setCommandEcho; + function setFailed(message) { + process.exitCode = ExitCode.Failure; + error(message); + } + exports2.setFailed = setFailed; + function isDebug() { + return process.env["RUNNER_DEBUG"] === "1"; + } + exports2.isDebug = isDebug; + function debug3(message) { + (0, command_1.issueCommand)("debug", {}, message); + } + exports2.debug = debug3; + function error(message, properties = {}) { + (0, command_1.issueCommand)("error", (0, utils_1.toCommandProperties)(properties), message instanceof Error ? message.toString() : message); + } + exports2.error = error; + function warning(message, properties = {}) { + (0, command_1.issueCommand)("warning", (0, utils_1.toCommandProperties)(properties), message instanceof Error ? message.toString() : message); + } + exports2.warning = warning; + function notice(message, properties = {}) { + (0, command_1.issueCommand)("notice", (0, utils_1.toCommandProperties)(properties), message instanceof Error ? message.toString() : message); + } + exports2.notice = notice; + function info(message) { + process.stdout.write(message + os3.EOL); + } + exports2.info = info; + function startGroup(name) { + (0, command_1.issue)("group", name); + } + exports2.startGroup = startGroup; + function endGroup() { + (0, command_1.issue)("endgroup"); + } + exports2.endGroup = endGroup; + function group(name, fn) { + return __awaiter(this, void 0, void 0, function* () { + startGroup(name); + let result; + try { + result = yield fn(); + } finally { + endGroup(); + } + return result; + }); + } + exports2.group = group; + function saveState(name, value) { + const filePath = process.env["GITHUB_STATE"] || ""; + if (filePath) { + return (0, file_command_1.issueFileCommand)("STATE", (0, file_command_1.prepareKeyValueMessage)(name, value)); + } + (0, command_1.issueCommand)("save-state", { name }, (0, utils_1.toCommandValue)(value)); + } + exports2.saveState = saveState; + function getState(name) { + return process.env[`STATE_${name}`] || ""; + } + exports2.getState = getState; + function getIDToken(aud) { + return __awaiter(this, void 0, void 0, function* () { + return yield oidc_utils_1.OidcClient.getIDToken(aud); + }); + } + exports2.getIDToken = getIDToken; + var summary_1 = require_summary(); + Object.defineProperty(exports2, "summary", { enumerable: true, get: function() { + return summary_1.summary; + } }); + var summary_2 = require_summary(); + Object.defineProperty(exports2, "markdownSummary", { enumerable: true, get: function() { + return summary_2.markdownSummary; + } }); + var path_utils_1 = require_path_utils(); + Object.defineProperty(exports2, "toPosixPath", { enumerable: true, get: function() { + return path_utils_1.toPosixPath; + } }); + Object.defineProperty(exports2, "toWin32Path", { enumerable: true, get: function() { + return path_utils_1.toWin32Path; + } }); + Object.defineProperty(exports2, "toPlatformPath", { enumerable: true, get: function() { + return path_utils_1.toPlatformPath; + } }); + exports2.platform = __importStar(require_platform()); + } +}); + // node_modules/@actions/github/lib/context.js var require_context = __commonJS({ "node_modules/@actions/github/lib/context.js"(exports2) { @@ -20336,12 +20138,12 @@ var require_dist_node2 = __commonJS({ } return to; }; - var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var dist_src_exports = {}; __export2(dist_src_exports, { endpoint: () => endpoint }); - module2.exports = __toCommonJS2(dist_src_exports); + module2.exports = __toCommonJS(dist_src_exports); var import_universal_user_agent = require_dist_node(); var VERSION5 = "9.0.6"; var userAgent = `octokit-endpoint.js/${VERSION5} ${(0, import_universal_user_agent.getUserAgent)()}`; @@ -20582,7 +20384,7 @@ var require_dist_node2 = __commonJS({ return template.replace(/\/$/, ""); } } - function parse2(options) { + function parse(options) { let method = options.method.toUpperCase(); let url2 = (options.url || "/").replace(/:([a-z]\w+)/g, "{$1}"); let headers = Object.assign({}, options.headers); @@ -20646,7 +20448,7 @@ var require_dist_node2 = __commonJS({ ); } function endpointWithDefaults(defaults2, route, options) { - return parse2(merge2(defaults2, route, options)); + return parse(merge2(defaults2, route, options)); } function withDefaults(oldDefaults, newDefaults) { const DEFAULTS2 = merge2(oldDefaults, newDefaults); @@ -20655,7 +20457,7 @@ var require_dist_node2 = __commonJS({ DEFAULTS: DEFAULTS2, defaults: withDefaults.bind(null, DEFAULTS2), merge: merge2.bind(null, DEFAULTS2), - parse: parse2 + parse }); } var endpoint = withDefaults(null, DEFAULTS); @@ -20784,12 +20586,12 @@ var require_dist_node4 = __commonJS({ isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, mod )); - var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var dist_src_exports = {}; __export2(dist_src_exports, { RequestError: () => RequestError }); - module2.exports = __toCommonJS2(dist_src_exports); + module2.exports = __toCommonJS(dist_src_exports); var import_deprecation = require_dist_node3(); var import_once = __toESM2(require_once()); var logOnceCode = (0, import_once.default)((deprecation) => console.warn(deprecation)); @@ -20866,12 +20668,12 @@ var require_dist_node5 = __commonJS({ } return to; }; - var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var dist_src_exports = {}; __export2(dist_src_exports, { request: () => request3 }); - module2.exports = __toCommonJS2(dist_src_exports); + module2.exports = __toCommonJS(dist_src_exports); var import_endpoint = require_dist_node2(); var import_universal_user_agent = require_dist_node(); var VERSION5 = "8.4.1"; @@ -20900,16 +20702,16 @@ var require_dist_node5 = __commonJS({ let headers = {}; let status; let url2; - let { fetch: fetch4 } = globalThis; + let { fetch: fetch5 } = globalThis; if ((_b2 = requestOptions.request) == null ? void 0 : _b2.fetch) { - fetch4 = requestOptions.request.fetch; + fetch5 = requestOptions.request.fetch; } - if (!fetch4) { + if (!fetch5) { throw new Error( "fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}). Learn more at https://github.com/octokit/octokit.js/#fetch-missing" ); } - return fetch4(requestOptions.url, { + return fetch5(requestOptions.url, { method: requestOptions.method, body: requestOptions.body, redirect: (_c2 = requestOptions.request) == null ? void 0 : _c2.redirect, @@ -21076,14 +20878,14 @@ var require_dist_node6 = __commonJS({ } return to; }; - var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var index_exports = {}; __export2(index_exports, { GraphqlResponseError: () => GraphqlResponseError, graphql: () => graphql2, withCustomRequest: () => withCustomRequest }); - module2.exports = __toCommonJS2(index_exports); + module2.exports = __toCommonJS(index_exports); var import_request3 = require_dist_node5(); var import_universal_user_agent = require_dist_node(); var VERSION5 = "7.1.1"; @@ -21213,12 +21015,12 @@ var require_dist_node7 = __commonJS({ } return to; }; - var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var dist_src_exports = {}; __export2(dist_src_exports, { createTokenAuth: () => createTokenAuth }); - module2.exports = __toCommonJS2(dist_src_exports); + module2.exports = __toCommonJS(dist_src_exports); var REGEX_IS_INSTALLATION_LEGACY = /^v1\./; var REGEX_IS_INSTALLATION = /^ghs_/; var REGEX_IS_USER_TO_SERVER = /^ghu_/; @@ -21284,12 +21086,12 @@ var require_dist_node8 = __commonJS({ } return to; }; - var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var index_exports = {}; __export2(index_exports, { Octokit: () => Octokit }); - module2.exports = __toCommonJS2(index_exports); + module2.exports = __toCommonJS(index_exports); var import_universal_user_agent = require_dist_node(); var import_before_after_hook = require_before_after_hook(); var import_request = require_dist_node5(); @@ -21443,13 +21245,13 @@ var require_dist_node9 = __commonJS({ } return to; }; - var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var dist_src_exports = {}; __export2(dist_src_exports, { legacyRestEndpointMethods: () => legacyRestEndpointMethods, restEndpointMethods: () => restEndpointMethods }); - module2.exports = __toCommonJS2(dist_src_exports); + module2.exports = __toCommonJS(dist_src_exports); var VERSION5 = "10.4.1"; var Endpoints = { actions: { @@ -23599,7 +23401,7 @@ var require_dist_node10 = __commonJS({ } return to; }; - var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var dist_src_exports = {}; __export2(dist_src_exports, { composePaginateRest: () => composePaginateRest, @@ -23607,7 +23409,7 @@ var require_dist_node10 = __commonJS({ paginateRest: () => paginateRest, paginatingEndpoints: () => paginatingEndpoints }); - module2.exports = __toCommonJS2(dist_src_exports); + module2.exports = __toCommonJS(dist_src_exports); var VERSION5 = "9.2.2"; function normalizePaginatedListResponse(response) { if (!response.data) { @@ -24267,11 +24069,11 @@ var require_main2 = __commonJS({ var fs4 = require("fs"); var path2 = require("path"); var os3 = require("os"); - var crypto6 = require("crypto"); + var crypto3 = require("crypto"); var packageJson = require_package(); - var version2 = packageJson.version; + var version = packageJson.version; var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg; - function parse2(src) { + function parse(src) { const obj = {}; let lines = src.toString(); lines = lines.replace(/\r\n?/mg, "\n"); @@ -24316,13 +24118,13 @@ var require_main2 = __commonJS({ return DotenvModule.parse(decrypted); } function _log(message) { - console.log(`[dotenv@${version2}][INFO] ${message}`); + console.log(`[dotenv@${version}][INFO] ${message}`); } function _warn(message) { - console.log(`[dotenv@${version2}][WARN] ${message}`); + console.log(`[dotenv@${version}][WARN] ${message}`); } function _debug(message) { - console.log(`[dotenv@${version2}][DEBUG] ${message}`); + console.log(`[dotenv@${version}][DEBUG] ${message}`); } function _dotenvKey(options) { if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) { @@ -24463,7 +24265,7 @@ var require_main2 = __commonJS({ const authTag = ciphertext.subarray(-16); ciphertext = ciphertext.subarray(12, -16); try { - const aesgcm = crypto6.createDecipheriv("aes-256-gcm", key, nonce); + const aesgcm = crypto3.createDecipheriv("aes-256-gcm", key, nonce); aesgcm.setAuthTag(authTag); return `${aesgcm.update(ciphertext)}${aesgcm.final()}`; } catch (error) { @@ -24514,7 +24316,7 @@ var require_main2 = __commonJS({ _parseVault, config: config6, decrypt, - parse: parse2, + parse, populate }; module2.exports.configDotenv = DotenvModule.configDotenv; @@ -27940,7 +27742,7 @@ var require_URL = __commonJS({ return; } const ctorRegistry = utils.initCtorRegistry(globalObject); - class URL3 { + class URL2 { constructor(url2) { if (arguments.length < 1) { throw new globalObject.TypeError( @@ -28233,7 +28035,7 @@ var require_URL = __commonJS({ return Impl.implementation.canParse(...args); } } - Object.defineProperties(URL3.prototype, { + Object.defineProperties(URL2.prototype, { toJSON: { enumerable: true }, href: { enumerable: true }, toString: { enumerable: true }, @@ -28250,18 +28052,18 @@ var require_URL = __commonJS({ hash: { enumerable: true }, [Symbol.toStringTag]: { value: "URL", configurable: true } }); - Object.defineProperties(URL3, { parse: { enumerable: true }, canParse: { enumerable: true } }); - ctorRegistry[interfaceName] = URL3; + Object.defineProperties(URL2, { parse: { enumerable: true }, canParse: { enumerable: true } }); + ctorRegistry[interfaceName] = URL2; Object.defineProperty(globalObject, interfaceName, { configurable: true, writable: true, - value: URL3 + value: URL2 }); if (globalNames.includes("Window")) { Object.defineProperty(globalObject, "webkitURL", { configurable: true, writable: true, - value: URL3 + value: URL2 }); } }; @@ -28273,9 +28075,9 @@ var require_URL = __commonJS({ var require_webidl2js_wrapper = __commonJS({ "node_modules/whatwg-url/webidl2js-wrapper.js"(exports2) { "use strict"; - var URL3 = require_URL(); + var URL2 = require_URL(); var URLSearchParams2 = require_URLSearchParams(); - exports2.URL = URL3; + exports2.URL = URL2; exports2.URLSearchParams = URLSearchParams2; } }); @@ -28284,11 +28086,11 @@ var require_webidl2js_wrapper = __commonJS({ var require_whatwg_url = __commonJS({ "node_modules/whatwg-url/index.js"(exports2) { "use strict"; - var { URL: URL3, URLSearchParams: URLSearchParams2 } = require_webidl2js_wrapper(); + var { URL: URL2, URLSearchParams: URLSearchParams2 } = require_webidl2js_wrapper(); var urlStateMachine = require_url_state_machine(); var percentEncoding = require_percent_encoding(); var sharedGlobalObject = { Array, Object, Promise, String, TypeError }; - URL3.install(sharedGlobalObject, ["Window"]); + URL2.install(sharedGlobalObject, ["Window"]); URLSearchParams2.install(sharedGlobalObject, ["Window"]); exports2.URL = sharedGlobalObject.URL; exports2.URLSearchParams = sharedGlobalObject.URLSearchParams; @@ -29133,12 +28935,12 @@ var require_lib3 = __commonJS({ configurable: true }); var INTERNALS$2 = Symbol("Request internals"); - var URL3 = Url.URL || whatwgUrl.URL; + var URL2 = Url.URL || whatwgUrl.URL; var parse_url = Url.parse; var format_url = Url.format; function parseURL(urlStr) { if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { - urlStr = new URL3(urlStr).toString(); + urlStr = new URL2(urlStr).toString(); } return parse_url(urlStr); } @@ -29302,12 +29104,12 @@ var require_lib3 = __commonJS({ const dest = new URL$1(destination).protocol; return orig === dest; }; - function fetch4(url2, opts) { - if (!fetch4.Promise) { + function fetch5(url2, opts) { + if (!fetch5.Promise) { throw new Error("native promise missing, set fetch.Promise to your favorite alternative"); } - Body.Promise = fetch4.Promise; - return new fetch4.Promise(function(resolve, reject) { + Body.Promise = fetch5.Promise; + return new fetch5.Promise(function(resolve, reject) { const request3 = new Request6(url2, opts); const options = getNodeRequestOptions(request3); const send = (options.protocol === "https:" ? https3 : http3).request; @@ -29378,7 +29180,7 @@ var require_lib3 = __commonJS({ req.on("response", function(res) { clearTimeout(reqTimeout); const headers = createHeadersLenient(res.headers); - if (fetch4.isRedirect(res.statusCode)) { + if (fetch5.isRedirect(res.statusCode)) { const location = headers.get("Location"); let locationURL = null; try { @@ -29440,7 +29242,7 @@ var require_lib3 = __commonJS({ requestOpts.body = void 0; requestOpts.headers.delete("content-length"); } - resolve(fetch4(new Request6(locationURL, requestOpts))); + resolve(fetch5(new Request6(locationURL, requestOpts))); finalize(); return; } @@ -29532,11 +29334,11 @@ var require_lib3 = __commonJS({ stream4.end(); } } - fetch4.isRedirect = function(code) { + fetch5.isRedirect = function(code) { return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; }; - fetch4.Promise = global.Promise; - module2.exports = exports2 = fetch4; + fetch5.Promise = global.Promise; + module2.exports = exports2 = fetch5; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.default = exports2; exports2.Headers = Headers6; @@ -31622,7 +31424,7 @@ var require_ms = __commonJS({ options = options || {}; var type2 = typeof val; if (type2 === "string" && val.length > 0) { - return parse2(val); + return parse(val); } else if (type2 === "number" && isFinite(val)) { return options.long ? fmtLong(val) : fmtShort(val); } @@ -31630,7 +31432,7 @@ var require_ms = __commonJS({ "val is not a non-empty string or a valid number. val=" + JSON.stringify(val) ); }; - function parse2(str2) { + function parse(str2) { str2 = String(str2); if (str2.length > 100) { return; @@ -47115,10 +46917,10 @@ var require_supports_color = __commonJS({ return 3; } if ("TERM_PROGRAM" in env2) { - const version2 = parseInt((env2.TERM_PROGRAM_VERSION || "").split(".")[0], 10); + const version = parseInt((env2.TERM_PROGRAM_VERSION || "").split(".")[0], 10); switch (env2.TERM_PROGRAM) { case "iTerm.app": - return version2 >= 3 ? 3 : 2; + return version >= 3 ? 3 : 2; case "Apple_Terminal": return 2; } @@ -47355,7 +47157,7 @@ var require_debug = __commonJS({ var require_follow_redirects = __commonJS({ "node_modules/follow-redirects/index.js"(exports2, module2) { var url2 = require("url"); - var URL3 = url2.URL; + var URL2 = url2.URL; var http3 = require("http"); var https3 = require("https"); var Writable = require("stream").Writable; @@ -47363,7 +47165,7 @@ var require_follow_redirects = __commonJS({ var debug3 = require_debug(); var useNativeURL = false; try { - assert(new URL3()); + assert(new URL2()); } catch (error) { useNativeURL = error.code === "ERR_INVALID_URL"; } @@ -47743,7 +47545,7 @@ var require_follow_redirects = __commonJS({ function parseUrl(input) { var parsed; if (useNativeURL) { - parsed = new URL3(input); + parsed = new URL2(input); } else { parsed = validateUrl(url2.parse(input)); if (!isString2(parsed.protocol)) { @@ -47753,7 +47555,7 @@ var require_follow_redirects = __commonJS({ return parsed; } function resolveUrl(relative, base) { - return useNativeURL ? new URL3(relative, base) : parseUrl(url2.resolve(base, relative)); + return useNativeURL ? new URL2(relative, base) : parseUrl(url2.resolve(base, relative)); } function validateUrl(input) { if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) { @@ -47830,7 +47632,7 @@ var require_follow_redirects = __commonJS({ return typeof value === "object" && "length" in value; } function isURL(value) { - return URL3 && value instanceof URL3; + return URL2 && value instanceof URL2; } module2.exports = wrap({ http: http3, https: https3 }); module2.exports.wrap = wrap; @@ -47991,12 +47793,12 @@ var require_tiktoken_bg = __commonJS({ wasm.tiktoken_name(retptr, this.__wbg_ptr); var r0 = getInt32Memory0()[retptr / 4 + 0]; var r1 = getInt32Memory0()[retptr / 4 + 1]; - let v12; + let v1; if (r0 !== 0) { - v12 = getStringFromWasm0(r0, r1).slice(); + v1 = getStringFromWasm0(r0, r1).slice(); wasm.__wbindgen_export_2(r0, r1 * 1, 1); } - return v12; + return v1; } finally { wasm.__wbindgen_add_to_stack_pointer(16); } @@ -48125,9 +47927,9 @@ var require_tiktoken_bg = __commonJS({ wasm.tiktoken_decode_single_token_bytes(retptr, this.__wbg_ptr, token); var r0 = getInt32Memory0()[retptr / 4 + 0]; var r1 = getInt32Memory0()[retptr / 4 + 1]; - var v12 = getArrayU8FromWasm0(r0, r1).slice(); + var v1 = getArrayU8FromWasm0(r0, r1).slice(); wasm.__wbindgen_export_2(r0, r1 * 1, 1); - return v12; + return v1; } finally { wasm.__wbindgen_add_to_stack_pointer(16); } @@ -50512,7 +50314,7 @@ var require_stringify = __commonJS({ return typeof v2 === "string" || typeof v2 === "number" || typeof v2 === "boolean" || typeof v2 === "symbol" || typeof v2 === "bigint"; }; var sentinel = {}; - var stringify3 = function stringify4(object, prefix, generateArrayPrefix, commaRoundTrip, allowEmptyArrays, strictNullHandling, skipNulls, encodeDotInKeys, encoder, filter2, sort, allowDots, serializeDate, format, formatter, encodeValuesOnly, charset, sideChannel) { + var stringify2 = function stringify3(object, prefix, generateArrayPrefix, commaRoundTrip, allowEmptyArrays, strictNullHandling, skipNulls, encodeDotInKeys, encoder, filter2, sort, allowDots, serializeDate, format, formatter, encodeValuesOnly, charset, sideChannel) { var obj = object; var tmpSc = sideChannel; var step = 0; @@ -50588,7 +50390,7 @@ var require_stringify = __commonJS({ sideChannel.set(object, step); var valueSideChannel = getSideChannel(); valueSideChannel.set(sentinel, sideChannel); - pushToArray(values, stringify4( + pushToArray(values, stringify3( value, keyPrefix, generateArrayPrefix, @@ -50704,7 +50506,7 @@ var require_stringify = __commonJS({ if (options.skipNulls && obj[key] === null) { continue; } - pushToArray(keys, stringify3( + pushToArray(keys, stringify2( obj[key], key, generateArrayPrefix, @@ -50970,13 +50772,13 @@ var require_parse2 = __commonJS({ var require_lib4 = __commonJS({ "node_modules/qs/lib/index.js"(exports2, module2) { "use strict"; - var stringify3 = require_stringify(); - var parse2 = require_parse2(); + var stringify2 = require_stringify(); + var parse = require_parse2(); var formats = require_formats(); module2.exports = { formats, - parse: parse2, - stringify: stringify3 + parse, + stringify: stringify2 }; } }); @@ -51079,8 +50881,8 @@ var require_custom_user_agent = __commonJS({ var config_1 = require_config(); var CustomUserAgentHook = class { beforeRequest(_3, request3) { - const version2 = config_1.SDK_METADATA.sdkVersion; - const ua = `mistral-client-typescript/${version2}`; + const version = config_1.SDK_METADATA.sdkVersion; + const ua = `mistral-client-typescript/${version}`; request3.headers.set("user-agent", ua); if (!request3.headers.get("user-agent")) { request3.headers.set("x-mistral-user-agent", ua); @@ -52209,11 +52011,11 @@ var require_types = __commonJS({ return new RegExp(`^${regex}$`); } exports2.datetimeRegex = datetimeRegex; - function isValidIP(ip, version2) { - if ((version2 === "v4" || !version2) && ipv4Regex.test(ip)) { + function isValidIP(ip, version) { + if ((version === "v4" || !version) && ipv4Regex.test(ip)) { return true; } - if ((version2 === "v6" || !version2) && ipv6Regex.test(ip)) { + if ((version === "v6" || !version) && ipv6Regex.test(ip)) { return true; } return false; @@ -55371,7 +55173,7 @@ var require_base64 = __commonJS({ exports2.zodInbound = exports2.zodOutbound = void 0; exports2.bytesToBase64 = bytesToBase64; exports2.bytesFromBase64 = bytesFromBase64; - exports2.stringToBytes = stringToBytes2; + exports2.stringToBytes = stringToBytes; exports2.stringFromBytes = stringFromBytes; exports2.stringToBase64 = stringToBase64; exports2.stringFromBase64 = stringFromBase64; @@ -55382,19 +55184,19 @@ var require_base64 = __commonJS({ function bytesFromBase64(encoded) { return Uint8Array.from(atob(encoded), (c2) => c2.charCodeAt(0)); } - function stringToBytes2(str2) { + function stringToBytes(str2) { return new TextEncoder().encode(str2); } function stringFromBytes(u8arr) { return new TextDecoder().decode(u8arr); } function stringToBase64(str2) { - return bytesToBase64(stringToBytes2(str2)); + return bytesToBase64(stringToBytes(str2)); } function stringFromBase64(b64str) { return stringFromBytes(bytesFromBase64(b64str)); } - exports2.zodOutbound = z3.instanceof(Uint8Array).or(z3.string().transform(stringToBytes2)); + exports2.zodOutbound = z3.instanceof(Uint8Array).or(z3.string().transform(stringToBytes)); exports2.zodInbound = z3.instanceof(Uint8Array).or(z3.string().transform(bytesFromBase64)); } }); @@ -56733,13 +56535,13 @@ var require_schemas = __commonJS({ "node_modules/@mistralai/mistralai/lib/schemas.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.parse = parse2; + exports2.parse = parse; exports2.safeParse = safeParse; exports2.collectExtraKeys = collectExtraKeys; var zod_1 = require_lib5(); var sdkvalidationerror_js_1 = require_sdkvalidationerror(); var fp_js_1 = require_fp(); - function parse2(rawValue, fn, errorMessage) { + function parse(rawValue, fn, errorMessage) { try { return fn(rawValue); } catch (err) { @@ -70280,10 +70082,10 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) { return 3; } if ("TERM_PROGRAM" in env) { - const version2 = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10); + const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10); switch (env.TERM_PROGRAM) { case "iTerm.app": { - return version2 >= 3 ? 3 : 2; + return version >= 3 ? 3 : 2; } case "Apple_Terminal": { return 2; @@ -74907,7 +74709,7 @@ var transitional_default = { }; // node_modules/axios/lib/platform/node/index.js -var import_crypto4 = __toESM(require("crypto"), 1); +var import_crypto = __toESM(require("crypto"), 1); // node_modules/axios/lib/platform/node/classes/URLSearchParams.js var import_url = __toESM(require("url"), 1); @@ -74925,7 +74727,7 @@ var generateString = (size = 16, alphabet2 = ALPHABET.ALPHA_DIGIT) => { let str2 = ""; const { length } = alphabet2; const randomValues = new Uint32Array(size); - import_crypto4.default.randomFillSync(randomValues); + import_crypto.default.randomFillSync(randomValues); for (let i3 = 0; i3 < size; i3++) { str2 += alphabet2[randomValues[i3] % length]; } @@ -77054,23 +76856,23 @@ var validators = {}; }; }); var deprecatedWarnings = {}; -validators.transitional = function transitional(validator, version2, message) { +validators.transitional = function transitional(validator, version, message) { function formatMessage(opt, desc) { return "[Axios v" + VERSION2 + "] Transitional option '" + opt + "'" + desc + (message ? ". " + message : ""); } return (value, opt, opts) => { if (validator === false) { throw new AxiosError_default( - formatMessage(opt, " has been removed" + (version2 ? " in " + version2 : "")), + formatMessage(opt, " has been removed" + (version ? " in " + version : "")), AxiosError_default.ERR_DEPRECATED ); } - if (version2 && !deprecatedWarnings[opt]) { + if (version && !deprecatedWarnings[opt]) { deprecatedWarnings[opt] = true; console.warn( formatMessage( opt, - " has been deprecated since v" + version2 + " and will be removed in the near future" + " has been deprecated since v" + version + " and will be removed in the near future" ) ); } @@ -77692,9 +77494,9 @@ function getErrorMessage(e3) { } // node_modules/@azure/core-util/dist/esm/uuidUtils.js -var import_crypto5 = require("crypto"); +var import_crypto2 = require("crypto"); var _a2; -var uuidFunction = typeof ((_a2 = globalThis === null || globalThis === void 0 ? void 0 : globalThis.crypto) === null || _a2 === void 0 ? void 0 : _a2.randomUUID) === "function" ? globalThis.crypto.randomUUID.bind(globalThis.crypto) : import_crypto5.randomUUID; +var uuidFunction = typeof ((_a2 = globalThis === null || globalThis === void 0 ? void 0 : globalThis.crypto) === null || _a2 === void 0 ? void 0 : _a2.randomUUID) === "function" ? globalThis.crypto.randomUUID.bind(globalThis.crypto) : import_crypto2.randomUUID; function randomUUID() { return uuidFunction(); } @@ -77796,8 +77598,8 @@ function __asyncValues(o3) { }; } function settle2(resolve, reject, d5, v2) { - Promise.resolve(v2).then(function(v6) { - resolve({ value: v6, done: d5 }); + Promise.resolve(v2).then(function(v3) { + resolve({ value: v3, done: d5 }); }, reject); } } @@ -81300,8 +81102,8 @@ function nonAzurePolicy() { } // node_modules/@azure/openai/dist-esm/src/OpenAIClient.js -function createOpenAIEndpoint(version2) { - return `https://api.openai.com/v${version2}`; +function createOpenAIEndpoint(version) { + return `https://api.openai.com/v${version}`; } function isCred(cred) { return isTokenCredential(cred) || cred.key !== void 0; @@ -87391,10 +87193,10 @@ function getEngine() { var COMMITLINT_LLM_CONFIG_PATH = `${process.env.PWD}/.opencommit-commitlint`; // src/modules/commitlint/crypto.ts -var import_crypto6 = __toESM(require("crypto"), 1); +var import_crypto3 = __toESM(require("crypto"), 1); var computeHash = async (content, algorithm = "sha256") => { try { - const hash = import_crypto6.default.createHash(algorithm); + const hash = import_crypto3.default.createHash(algorithm); hash.update(content); return hash.digest("hex"); } catch (error) { @@ -88043,106 +87845,111 @@ function sleep3(ms) { } // src/github-action.ts +var import_node_fetch = __toESM(require_lib3(), 1); var GITHUB_TOKEN = import_core22.default.getInput("GITHUB_TOKEN"); +var DRY_RUN = import_core22.default.getInput("DRY_RUN") === "true"; +var ocPrefix = "[OpenCommit]"; +var PLATFORM = (process.env.GIT_PLATFORM || "github").toLowerCase(); var octokit = import_github.default.getOctokit(GITHUB_TOKEN); var context = import_github.default.context; var owner = context.repo.owner; var repo = context.repo.repo; -async function getCommitDiff(commitSha) { - const diffResponse = await octokit.request( - "GET /repos/{owner}/{repo}/commits/{ref}", - { - owner, - repo, - ref: commitSha, - headers: { - Accept: "application/vnd.github.v3.diff" +async function fetchDiffFromAPI(commitSha) { + if (PLATFORM === "github") { + const resp = await octokit.request( + "GET /repos/{owner}/{repo}/commits/{ref}", + { + owner, + repo, + ref: commitSha, + headers: { Accept: "application/vnd.github.v3.diff" } } - } - ); - return { sha: commitSha, diff: diffResponse.data }; + ); + return resp.data; + } else { + const diffUrl = `${process.env.GIT_PLATFORM_API_BASE}/repos/${owner}/${repo}/git/commits/${commitSha}.diff`; + const response = await (0, import_node_fetch.default)(diffUrl, { + headers: { Authorization: `token ${GITHUB_TOKEN}` } + }); + return response.text(); + } +} +async function getCommitDiff(commitSha) { + const diff = await fetchDiffFromAPI(commitSha); + return { sha: commitSha, diff }; +} +function filterCommits(commits) { + return commits.filter(({ message }) => { + if (message.startsWith("Merge")) return false; + if (message.startsWith(ocPrefix)) return false; + return true; + }); } async function improveMessagesInChunks(diffsAndSHAs) { const chunkSize = diffsAndSHAs.length % 2 === 0 ? 4 : 3; ce(`Improving commit messages in chunks of ${chunkSize}.`); const improvePromises = diffsAndSHAs.map( - (commit) => generateCommitMessageByDiff(commit.diff, false) + (c2) => generateCommitMessageByDiff(c2.diff, false) ); - let improvedMessagesAndSHAs = []; + let improved = []; for (let step = 0; step < improvePromises.length; step += chunkSize) { - const chunkOfPromises = improvePromises.slice(step, step + chunkSize); + const chunkPromises = improvePromises.slice(step, step + chunkSize); try { - const chunkOfImprovedMessages = await Promise.all(chunkOfPromises); - const chunkOfImprovedMessagesBySha = chunkOfImprovedMessages.map( - (improvedMsg, i3) => { - const index = improvedMessagesAndSHAs.length; - const sha = diffsAndSHAs[index + i3].sha; - return { sha, msg: improvedMsg }; - } + const results = await Promise.all(chunkPromises); + results.forEach((msg, idx) => { + const sha = diffsAndSHAs[improved.length + idx].sha; + improved.push({ sha, msg }); + }); + await sleep3( + 1e3 * randomIntFromInterval(1, 5) + 100 * randomIntFromInterval(1, 5) ); - improvedMessagesAndSHAs.push(...chunkOfImprovedMessagesBySha); - const sleepFor = 1e3 * randomIntFromInterval(1, 5) + 100 * randomIntFromInterval(1, 5); - ce( - `Improved ${chunkOfPromises.length} messages. Sleeping for ${sleepFor}` - ); - await sleep3(sleepFor); - } catch (error) { - ce(error); - const sleepFor = 6e4 + 1e3 * randomIntFromInterval(1, 5); - ce(`Retrying after sleeping for ${sleepFor}`); - await sleep3(sleepFor); + } catch (e3) { + const wait = 6e4 + 1e3 * randomIntFromInterval(1, 5); + ce(`Retrying after ${wait}`); + await sleep3(wait); step -= chunkSize; } } - return improvedMessagesAndSHAs; + return improved; } -var getDiffsBySHAs = async (SHAs) => { - const diffPromises = SHAs.map((sha) => getCommitDiff(sha)); - const diffs = await Promise.all(diffPromises).catch((error) => { - ce(`Error in Promise.all(getCommitDiffs(SHAs)): ${error}.`); - throw error; - }); - return diffs; -}; -async function improveCommitMessages(commitsToImprove) { - if (commitsToImprove.length) { - ce(`Found ${commitsToImprove.length} commits to improve.`); - } else { - ce("No new commits found."); +async function improveCommitMessages(commits) { + const toImprove = filterCommits(commits); + if (!toImprove.length) { + ce("No eligible commits to improve."); return; } - ce("Fetching commit diffs by SHAs."); - const commitSHAsToImprove = commitsToImprove.map((commit) => commit.id); - const diffsWithSHAs = await getDiffsBySHAs(commitSHAsToImprove); - ce("Done."); - const improvedMessagesWithSHAs = await improveMessagesInChunks(diffsWithSHAs); - console.log( - `Improved ${improvedMessagesWithSHAs.length} commits: `, - improvedMessagesWithSHAs + const shas = toImprove.map((c2) => c2.id); + const diffs = await Promise.all(shas.map((sha) => getCommitDiff(sha))); + const improved = await improveMessagesInChunks(diffs); + const changesExist = improved.some( + ({ msg }, i3) => msg !== toImprove[i3].message ); - const messagesChanged = improvedMessagesWithSHAs.some( - ({ sha, msg }, index) => msg !== commitsToImprove[index].message - ); - if (!messagesChanged) { - console.log("No changes in commit messages detected, skipping rebase"); + if (!changesExist) { + ce("No commit message changes."); return; } - const createCommitMessageFile = (message, index) => (0, import_fs3.writeFileSync)(`./commit-${index}.txt`, message); - improvedMessagesWithSHAs.forEach( - ({ msg }, i3) => createCommitMessageFile(msg, i3) + if (DRY_RUN) { + ce("Dry\u2011run: logging proposed changes (no rebase/push)."); + improved.forEach( + ({ sha, msg }) => console.log(`Would rewrite ${sha} => ${msg}`) + ); + return; + } + improved.forEach( + ({ msg }, i3) => (0, import_fs3.writeFileSync)(`./commit-${i3}.txt`, msg) ); - (0, import_fs3.writeFileSync)(`./count.txt`, "0"); + (0, import_fs3.writeFileSync)("./count.txt", "0"); (0, import_fs3.writeFileSync)( "./rebase-exec.sh", `#!/bin/bash - count=$(cat count.txt) - git commit --amend -F commit-$count.txt - echo $(( count + 1 )) > count.txt` +count=$(cat count.txt) +git commit --amend -F commit-$count.txt +echo $((count+1)) > count.txt` ); - await import_exec.default.exec(`chmod +x ./rebase-exec.sh`); + await import_exec.default.exec("chmod +x ./rebase-exec.sh"); await import_exec.default.exec( "git", - ["rebase", `${commitsToImprove[0].id}^`, "--exec", "./rebase-exec.sh"], + ["rebase", `${shas[0]}^`, "--exec", "./rebase-exec.sh"], { env: { GIT_SEQUENCE_EDITOR: 'sed -i -e "s/^pick/reword/g"', @@ -88151,37 +87958,27 @@ async function improveCommitMessages(commitsToImprove) { } } ); - const deleteCommitMessageFile = (index) => (0, import_fs3.unlinkSync)(`./commit-${index}.txt`); - commitsToImprove.forEach((_commit, i3) => deleteCommitMessageFile(i3)); + toImprove.forEach((_c2, i3) => (0, import_fs3.unlinkSync)(`./commit-${i3}.txt`)); (0, import_fs3.unlinkSync)("./count.txt"); (0, import_fs3.unlinkSync)("./rebase-exec.sh"); - ce("Force pushing non-interactively rebased commits into remote."); - await import_exec.default.exec("git", ["status"]); - await import_exec.default.exec("git", ["push", `--force`]); - ce("Done \u{1F9D9}"); + await import_exec.default.exec("git", ["push", "--force"]); + ce("Done"); } async function run() { - ae("OpenCommit \u2014 improving lame commit messages"); + ae("OpenCommit \u2014 improving commit messages"); try { - if (import_github.default.context.eventName === "push") { - ce(`Processing commits in a Push event`); - const payload = import_github.default.context.payload; - const commits = payload.commits; - if (payload.pusher.email) - await import_exec.default.exec("git", ["config", "user.email", payload.pusher.email]); + if (context.eventName === "push") { + const payload = context.payload; + await import_exec.default.exec("git", ["config", "user.email", payload.pusher.email]); await import_exec.default.exec("git", ["config", "user.name", payload.pusher.name]); - await import_exec.default.exec("git", ["status"]); - await import_exec.default.exec("git", ["log", "--oneline"]); - await improveCommitMessages(commits); + await improveCommitMessages(payload.commits); } else { - ce("Wrong action."); import_core22.default.error( - `OpenCommit was called on ${import_github.default.context.payload.action}. OpenCommit is supposed to be used on "push" action.` + `Wrong event: expected push, got ${context.eventName}` ); } } catch (error) { - const err = error?.message || error; - import_core22.default.setFailed(err); + import_core22.default.setFailed(error.message || String(error)); } } run(); diff --git a/src/github-action.ts b/src/github-action.ts index 79592b4..f3c86ef 100644 --- a/src/github-action.ts +++ b/src/github-action.ts @@ -8,11 +8,17 @@ import { generateCommitMessageByDiff } from './generateCommitMessageFromGitDiff' import { randomIntFromInterval } from './utils/randomIntFromInterval'; import { sleep } from './utils/sleep'; -// This should be a token with access to your repository scoped in as a secret. -// The YML workflow will need to set GITHUB_TOKEN with the GitHub Secret Token -// GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -// https://help.github.com/en/actions/automating-your-workflow-with-github-actions/authenticating-with-the-github_token#about-the-github_token-secret +// ------------ New Imports ------------ +import fetch from 'node-fetch'; + +// Inputs const GITHUB_TOKEN = core.getInput('GITHUB_TOKEN'); +const DRY_RUN = core.getInput('DRY_RUN') === 'true'; +const ocPrefix = '[OpenCommit]'; // Commit prefix to skip + +// Platforms: github | gitea | forgejo (via GIT_PLATFORM env) +const PLATFORM = (process.env.GIT_PLATFORM || 'github').toLowerCase(); + const octokit = github.getOctokit(GITHUB_TOKEN); const context = github.context; const owner = context.repo.owner; @@ -21,149 +27,132 @@ const repo = context.repo.repo; type SHA = string; type Diff = string; -async function getCommitDiff(commitSha: string) { - const diffResponse = await octokit.request( - 'GET /repos/{owner}/{repo}/commits/{ref}', - { - owner, - repo, - ref: commitSha, - headers: { - Accept: 'application/vnd.github.v3.diff' +async function fetchDiffFromAPI(commitSha: string) { + if (PLATFORM === 'github') { + const resp = await octokit.request( + 'GET /repos/{owner}/{repo}/commits/{ref}', + { + owner, + repo, + ref: commitSha, + headers: { Accept: 'application/vnd.github.v3.diff' } } - } - ); - return { sha: commitSha, diff: diffResponse.data }; + ); + return resp.data; + } else { + // Gitea/Forgejo unified diff endpoint + const diffUrl = `${process.env.GIT_PLATFORM_API_BASE}/repos/${owner}/${repo}/git/commits/${commitSha}.diff`; + const response = await fetch(diffUrl, { + headers: { Authorization: `token ${GITHUB_TOKEN}` } + }); + return response.text(); + } +} + +async function getCommitDiff(commitSha: string) { + const diff = await fetchDiffFromAPI(commitSha); + return { sha: commitSha, diff }; +} + +// Filter out merge commits and those already rewritten +function filterCommits( + commits: { id: string; message: string }[] +) { + return commits.filter(({ message }) => { + if (message.startsWith('Merge')) return false; + if (message.startsWith(ocPrefix)) return false; + return true; + }); } interface DiffAndSHA { sha: SHA; diff: Diff; } - interface MsgAndSHA { sha: SHA; msg: string; } -// send only 3-4 size chunks of diffs in steps, -// because openAI restricts "too many requests" at once with 429 error +// split into chunks for OpenAI async function improveMessagesInChunks(diffsAndSHAs: DiffAndSHA[]) { const chunkSize = diffsAndSHAs!.length % 2 === 0 ? 4 : 3; outro(`Improving commit messages in chunks of ${chunkSize}.`); - const improvePromises = diffsAndSHAs!.map((commit) => - generateCommitMessageByDiff(commit.diff, false) + const improvePromises = diffsAndSHAs!.map((c) => + generateCommitMessageByDiff(c.diff, false) ); - let improvedMessagesAndSHAs: MsgAndSHA[] = []; + let improved: MsgAndSHA[] = []; for (let step = 0; step < improvePromises.length; step += chunkSize) { - const chunkOfPromises = improvePromises.slice(step, step + chunkSize); - + const chunkPromises = improvePromises.slice(step, step + chunkSize); try { - const chunkOfImprovedMessages = await Promise.all(chunkOfPromises); - - const chunkOfImprovedMessagesBySha = chunkOfImprovedMessages.map( - (improvedMsg, i) => { - const index = improvedMessagesAndSHAs.length; - const sha = diffsAndSHAs![index + i].sha; - - return { sha, msg: improvedMsg }; - } + const results = await Promise.all(chunkPromises); + results.forEach((msg, idx) => { + const sha = diffsAndSHAs![improved.length + idx].sha; + improved.push({ sha, msg }); + }); + await sleep( + 1000 * randomIntFromInterval(1, 5) + + 100 * randomIntFromInterval(1, 5) ); - - improvedMessagesAndSHAs.push(...chunkOfImprovedMessagesBySha); - - // sometimes openAI errors with 429 code (too many requests), - // so lets sleep a bit - const sleepFor = - 1000 * randomIntFromInterval(1, 5) + 100 * randomIntFromInterval(1, 5); - - outro( - `Improved ${chunkOfPromises.length} messages. Sleeping for ${sleepFor}` - ); - - await sleep(sleepFor); - } catch (error) { - outro(error as string); - - // if sleeping in try block still fails with 429, - // openAI wants at least 1 minute before next request - const sleepFor = 60000 + 1000 * randomIntFromInterval(1, 5); - outro(`Retrying after sleeping for ${sleepFor}`); - await sleep(sleepFor); - - // go to previous step + } catch (e) { + const wait = 60000 + 1000 * randomIntFromInterval(1, 5); + outro(`Retrying after ${wait}`); + await sleep(wait); step -= chunkSize; } } - - return improvedMessagesAndSHAs; + return improved; } -const getDiffsBySHAs = async (SHAs: string[]) => { - const diffPromises = SHAs.map((sha) => getCommitDiff(sha)); - - const diffs = await Promise.all(diffPromises).catch((error) => { - outro(`Error in Promise.all(getCommitDiffs(SHAs)): ${error}.`); - throw error; - }); - - return diffs; -}; - async function improveCommitMessages( - commitsToImprove: { id: string; message: string }[] -): Promise { - if (commitsToImprove.length) { - outro(`Found ${commitsToImprove.length} commits to improve.`); - } else { - outro('No new commits found.'); + commits: { id: string; message: string }[] +) { + const toImprove = filterCommits(commits); + if (!toImprove.length) { + outro('No eligible commits to improve.'); return; } - outro('Fetching commit diffs by SHAs.'); - const commitSHAsToImprove = commitsToImprove.map((commit) => commit.id); - const diffsWithSHAs = await getDiffsBySHAs(commitSHAsToImprove); - outro('Done.'); + const shas = toImprove.map((c) => c.id); + const diffs = await Promise.all(shas.map((sha) => getCommitDiff(sha))); - const improvedMessagesWithSHAs = await improveMessagesInChunks(diffsWithSHAs); + const improved = await improveMessagesInChunks(diffs); - console.log( - `Improved ${improvedMessagesWithSHAs.length} commits: `, - improvedMessagesWithSHAs + const changesExist = improved.some( + ({ msg }, i) => msg !== toImprove[i].message ); - // Check if there are actually any changes in the commit messages - const messagesChanged = improvedMessagesWithSHAs.some( - ({ sha, msg }, index) => msg !== commitsToImprove[index].message - ); - - if (!messagesChanged) { - console.log('No changes in commit messages detected, skipping rebase'); + if (!changesExist) { + outro('No commit message changes.'); return; } - const createCommitMessageFile = (message: string, index: number) => - writeFileSync(`./commit-${index}.txt`, message); - improvedMessagesWithSHAs.forEach(({ msg }, i) => - createCommitMessageFile(msg, i) + if (DRY_RUN) { + outro('Dry‑run: logging proposed changes (no rebase/push).'); + improved.forEach(({ sha, msg }) => + console.log(`Would rewrite ${sha} => ${msg}`) + ); + return; + } + + improved.forEach(({ msg }, i) => + writeFileSync(`./commit-${i}.txt`, msg) ); - writeFileSync(`./count.txt`, '0'); - + writeFileSync('./count.txt', '0'); writeFileSync( './rebase-exec.sh', `#!/bin/bash - count=$(cat count.txt) - git commit --amend -F commit-$count.txt - echo $(( count + 1 )) > count.txt` +count=$(cat count.txt) +git commit --amend -F commit-$count.txt +echo $((count+1)) > count.txt` ); - await exec.exec(`chmod +x ./rebase-exec.sh`); - + await exec.exec('chmod +x ./rebase-exec.sh'); await exec.exec( 'git', - ['rebase', `${commitsToImprove[0].id}^`, '--exec', './rebase-exec.sh'], + ['rebase', `${shas[0]}^`, '--exec', './rebase-exec.sh'], { env: { GIT_SEQUENCE_EDITOR: 'sed -i -e "s/^pick/reword/g"', @@ -173,53 +162,31 @@ async function improveCommitMessages( } ); - const deleteCommitMessageFile = (index: number) => - unlinkSync(`./commit-${index}.txt`); - commitsToImprove.forEach((_commit, i) => deleteCommitMessageFile(i)); - + toImprove.forEach((_c, i) => unlinkSync(`./commit-${i}.txt`)); unlinkSync('./count.txt'); unlinkSync('./rebase-exec.sh'); - outro('Force pushing non-interactively rebased commits into remote.'); - - await exec.exec('git', ['status']); - - // Force push the rebased commits - await exec.exec('git', ['push', `--force`]); - - outro('Done 🧙'); + await exec.exec('git', ['push', '--force']); + outro('Done'); } async function run() { - intro('OpenCommit — improving lame commit messages'); - + intro('OpenCommit — improving commit messages'); try { - if (github.context.eventName === 'push') { - outro(`Processing commits in a Push event`); + if (context.eventName === 'push') { + const payload = context.payload as PushEvent; + await exec.exec('git', ['config', 'user.email', payload.pusher.email!]); + await exec.exec('git', ['config', 'user.name', payload.pusher.name!]); - const payload = github.context.payload as PushEvent; - const commits = payload.commits; - - // Set local Git user identity for future git history manipulations - if (payload.pusher.email) - await exec.exec('git', ['config', 'user.email', payload.pusher.email]); - - await exec.exec('git', ['config', 'user.name', payload.pusher.name]); - - await exec.exec('git', ['status']); - await exec.exec('git', ['log', '--oneline']); - - await improveCommitMessages(commits); + await improveCommitMessages(payload.commits); } else { - outro('Wrong action.'); core.error( - `OpenCommit was called on ${github.context.payload.action}. OpenCommit is supposed to be used on "push" action.` + `Wrong event: expected push, got ${context.eventName}` ); } } catch (error: any) { - const err = error?.message || error; - core.setFailed(err); + core.setFailed(error.message || String(error)); } } diff --git a/src/platform.ts b/src/platform.ts new file mode 100644 index 0000000..69c7471 --- /dev/null +++ b/src/platform.ts @@ -0,0 +1,96 @@ +// src/platform.ts +import { Gitea } from '@go-gitea/sdk.js'; +import github from '@actions/github'; +import { PushEvent } from '@octokit/webhooks-types'; + +export const REWRITE_MARKER = '[OPENCOMMIT]'; + +export type NormalizedCommit = { + id: string; + message: string; + author?: { name?: string; email?: string }; +}; + +export function isGitea(): boolean { + return !!process.env.GITEA_BASE_URL; +} + +export async function getPushCommits(): Promise { + if (isGitea()) { + const payload = github.context.payload as any; + const commits = payload.commits as Array; + + return commits + .filter((commit) => { + if (commit.message.startsWith('Merge')) return false; + if (commit.message.includes(REWRITE_MARKER)) return false; + return true; + }) + .map((commit) => ({ + id: commit.id, + message: commit.message, + author: commit.author + ? { + name: commit.author.name, + email: commit.author.email ?? undefined, // coerce null → undefined + } + : undefined, + })); + } else { + const payload = github.context.payload as PushEvent; + const commits = payload.commits; + + return commits + .filter((commit) => { + if (commit.message.startsWith('Merge')) return false; + if (commit.message.includes(REWRITE_MARKER)) return false; + return true; + }) + .map((commit) => ({ + id: commit.id, + message: commit.message, + author: { + name: commit.author.name, + email: commit.author.email ?? undefined, // coerce null → undefined + }, + })); + } +} + +export async function fetchCommitDiff( + sha: string, + giteaConfig?: { baseUrl: string; token: string } +): Promise<{ sha: string; diff: string }> { + if (isGitea() && giteaConfig) { + const gitea = new Gitea({ + baseUrl: giteaConfig.baseUrl, + auth: giteaConfig.token, + }); + + const { data } = await gitea.rest.git.getCommit({ + owner: process.env.GITEA_REPO_OWNER!, + repo: process.env.GITEA_REPO_NAME!, + sha, + }); + + const filesChanged = + data.files?.map((f: any) => `diff --git a/${f.filename} b/${f.filename}`).join('\n') ?? ''; + + return { sha, diff: filesChanged }; + } else { + const octokit = github.getOctokit(process.env.GITHUB_TOKEN!); + const context = github.context; + + const { data: diff } = await octokit.request( + 'GET /repos/{owner}/{repo}/commits/{ref}', + { + owner: context.repo.owner, + repo: context.repo.repo, + ref: sha, + headers: { Accept: 'application/vnd.github.v3.diff' }, + } + ); + + return { sha, diff }; + } +} diff --git a/test/e2e/gitPush.test.js b/test/e2e/gitPush.test.js new file mode 100644 index 0000000..7d60613 --- /dev/null +++ b/test/e2e/gitPush.test.js @@ -0,0 +1,134 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const path_1 = __importDefault(require("path")); +require("cli-testing-library/extend-expect"); +const child_process_1 = require("child_process"); +const utils_1 = require("./utils"); +const util_1 = require("util"); +const cli_testing_library_1 = require("cli-testing-library"); +const path_2 = require("path"); +const fs_1 = require("fs"); +const fsExec = (0, util_1.promisify)(child_process_1.exec); +const fsRemove = (0, util_1.promisify)(fs_1.rm); +/** + * git remote -v + * + * [no remotes] + */ +const prepareNoRemoteGitRepository = async () => { + const tempDir = await (0, utils_1.prepareTempDir)(); + await fsExec('git init test', { cwd: tempDir }); + const gitDir = path_1.default.resolve(tempDir, 'test'); + const cleanup = async () => { + return fsRemove(tempDir, { recursive: true }); + }; + return { + gitDir, + cleanup + }; +}; +/** + * git remote -v + * + * origin /tmp/remote.git (fetch) + * origin /tmp/remote.git (push) + */ +const prepareOneRemoteGitRepository = async () => { + const tempDir = await (0, utils_1.prepareTempDir)(); + await fsExec('git init --bare remote.git', { cwd: tempDir }); + await fsExec('git clone remote.git test', { cwd: tempDir }); + const gitDir = path_1.default.resolve(tempDir, 'test'); + const cleanup = async () => { + return fsRemove(tempDir, { recursive: true }); + }; + return { + gitDir, + cleanup + }; +}; +/** + * git remote -v + * + * origin /tmp/remote.git (fetch) + * origin /tmp/remote.git (push) + * other ../remote2.git (fetch) + * other ../remote2.git (push) + */ +const prepareTwoRemotesGitRepository = async () => { + const tempDir = await (0, utils_1.prepareTempDir)(); + await fsExec('git init --bare remote.git', { cwd: tempDir }); + await fsExec('git init --bare other.git', { cwd: tempDir }); + await fsExec('git clone remote.git test', { cwd: tempDir }); + const gitDir = path_1.default.resolve(tempDir, 'test'); + await fsExec('git remote add other ../other.git', { cwd: gitDir }); + const cleanup = async () => { + return fsRemove(tempDir, { recursive: true }); + }; + return { + gitDir, + cleanup + }; +}; +describe('cli flow to push git branch', () => { + it('do nothing when OCO_GITPUSH is set to false', async () => { + const { gitDir, cleanup } = await prepareNoRemoteGitRepository(); + await (0, cli_testing_library_1.render)('echo', [`'console.log("Hello World");' > index.ts`], { + cwd: gitDir + }); + await (0, cli_testing_library_1.render)('git', ['add index.ts'], { cwd: gitDir }); + const { queryByText, findByText, userEvent } = await (0, cli_testing_library_1.render)(`OCO_AI_PROVIDER='test' OCO_GITPUSH='false' node`, [(0, path_2.resolve)('./out/cli.cjs')], { cwd: gitDir }); + expect(await findByText('Confirm the commit message?')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + expect(await queryByText('Choose a remote to push to')).not.toBeInTheConsole(); + expect(await queryByText('Do you want to run `git push`?')).not.toBeInTheConsole(); + expect(await queryByText('Successfully pushed all commits to origin')).not.toBeInTheConsole(); + expect(await queryByText('Command failed with exit code 1')).not.toBeInTheConsole(); + await cleanup(); + }); + it('push and cause error when there is no remote', async () => { + const { gitDir, cleanup } = await prepareNoRemoteGitRepository(); + await (0, cli_testing_library_1.render)('echo', [`'console.log("Hello World");' > index.ts`], { + cwd: gitDir + }); + await (0, cli_testing_library_1.render)('git', ['add index.ts'], { cwd: gitDir }); + const { queryByText, findByText, userEvent } = await (0, cli_testing_library_1.render)(`OCO_AI_PROVIDER='test' OCO_GITPUSH='true' node`, [(0, path_2.resolve)('./out/cli.cjs')], { cwd: gitDir }); + expect(await findByText('Confirm the commit message?')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + expect(await queryByText('Choose a remote to push to')).not.toBeInTheConsole(); + expect(await queryByText('Do you want to run `git push`?')).not.toBeInTheConsole(); + expect(await queryByText('Successfully pushed all commits to origin')).not.toBeInTheConsole(); + expect(await findByText('Command failed with exit code 1')).toBeInTheConsole(); + await cleanup(); + }); + it('push when one remote is set', async () => { + const { gitDir, cleanup } = await prepareOneRemoteGitRepository(); + await (0, cli_testing_library_1.render)('echo', [`'console.log("Hello World");' > index.ts`], { + cwd: gitDir + }); + await (0, cli_testing_library_1.render)('git', ['add index.ts'], { cwd: gitDir }); + const { findByText, userEvent } = await (0, cli_testing_library_1.render)(`OCO_AI_PROVIDER='test' OCO_GITPUSH='true' node`, [(0, path_2.resolve)('./out/cli.cjs')], { cwd: gitDir }); + expect(await findByText('Confirm the commit message?')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + expect(await findByText('Do you want to run `git push`?')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + expect(await findByText('Successfully pushed all commits to origin')).toBeInTheConsole(); + await cleanup(); + }); + it('push when two remotes are set', async () => { + const { gitDir, cleanup } = await prepareTwoRemotesGitRepository(); + await (0, cli_testing_library_1.render)('echo', [`'console.log("Hello World");' > index.ts`], { + cwd: gitDir + }); + await (0, cli_testing_library_1.render)('git', ['add index.ts'], { cwd: gitDir }); + const { findByText, userEvent } = await (0, cli_testing_library_1.render)(`OCO_AI_PROVIDER='test' OCO_GITPUSH='true' node`, [(0, path_2.resolve)('./out/cli.cjs')], { cwd: gitDir }); + expect(await findByText('Confirm the commit message?')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + expect(await findByText('Choose a remote to push to')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + expect(await findByText('Successfully pushed all commits to origin')).toBeInTheConsole(); + await cleanup(); + }); +}); diff --git a/test/e2e/noChanges.test.js b/test/e2e/noChanges.test.js new file mode 100644 index 0000000..c637ed7 --- /dev/null +++ b/test/e2e/noChanges.test.js @@ -0,0 +1,12 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const path_1 = require("path"); +const cli_testing_library_1 = require("cli-testing-library"); +require("cli-testing-library/extend-expect"); +const utils_1 = require("./utils"); +it('cli flow when there are no changes', async () => { + const { gitDir, cleanup } = await (0, utils_1.prepareEnvironment)(); + const { findByText } = await (0, cli_testing_library_1.render)(`OCO_AI_PROVIDER='test' node`, [(0, path_1.resolve)('./out/cli.cjs')], { cwd: gitDir }); + expect(await findByText('No changes detected')).toBeInTheConsole(); + await cleanup(); +}); diff --git a/test/e2e/oneFile.test.js b/test/e2e/oneFile.test.js new file mode 100644 index 0000000..78d1498 --- /dev/null +++ b/test/e2e/oneFile.test.js @@ -0,0 +1,40 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const path_1 = require("path"); +const cli_testing_library_1 = require("cli-testing-library"); +require("cli-testing-library/extend-expect"); +const utils_1 = require("./utils"); +it('cli flow to generate commit message for 1 new file (staged)', async () => { + const { gitDir, cleanup } = await (0, utils_1.prepareEnvironment)(); + await (0, cli_testing_library_1.render)('echo', [`'console.log("Hello World");' > index.ts`], { cwd: gitDir }); + await (0, cli_testing_library_1.render)('git', ['add index.ts'], { cwd: gitDir }); + const { queryByText, findByText, userEvent } = await (0, cli_testing_library_1.render)(`OCO_AI_PROVIDER='test' OCO_GITPUSH='true' node`, [(0, path_1.resolve)('./out/cli.cjs')], { cwd: gitDir }); + expect(await queryByText('No files are staged')).not.toBeInTheConsole(); + expect(await queryByText('Do you want to stage all files and generate commit message?')).not.toBeInTheConsole(); + expect(await findByText('Generating the commit message')).toBeInTheConsole(); + expect(await findByText('Confirm the commit message?')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + expect(await findByText('Do you want to run `git push`?')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + expect(await findByText('Successfully pushed all commits to origin')).toBeInTheConsole(); + await cleanup(); +}); +it('cli flow to generate commit message for 1 changed file (not staged)', async () => { + const { gitDir, cleanup } = await (0, utils_1.prepareEnvironment)(); + await (0, cli_testing_library_1.render)('echo', [`'console.log("Hello World");' > index.ts`], { cwd: gitDir }); + await (0, cli_testing_library_1.render)('git', ['add index.ts'], { cwd: gitDir }); + await (0, cli_testing_library_1.render)('git', [`commit -m 'add new file'`], { cwd: gitDir }); + await (0, cli_testing_library_1.render)('echo', [`'console.log("Good night World");' >> index.ts`], { cwd: gitDir }); + const { findByText, userEvent } = await (0, cli_testing_library_1.render)(`OCO_AI_PROVIDER='test' OCO_GITPUSH='true' node`, [(0, path_1.resolve)('./out/cli.cjs')], { cwd: gitDir }); + expect(await findByText('No files are staged')).toBeInTheConsole(); + expect(await findByText('Do you want to stage all files and generate commit message?')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + expect(await findByText('Generating the commit message')).toBeInTheConsole(); + expect(await findByText('Confirm the commit message?')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + expect(await findByText('Successfully committed')).toBeInTheConsole(); + expect(await findByText('Do you want to run `git push`?')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + expect(await findByText('Successfully pushed all commits to origin')).toBeInTheConsole(); + await cleanup(); +}); diff --git a/test/e2e/prompt-module/commitlint.test.js b/test/e2e/prompt-module/commitlint.test.js new file mode 100644 index 0000000..d650659 --- /dev/null +++ b/test/e2e/prompt-module/commitlint.test.js @@ -0,0 +1,142 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const path_1 = require("path"); +const cli_testing_library_1 = require("cli-testing-library"); +require("cli-testing-library/extend-expect"); +const utils_1 = require("../utils"); +const path_2 = __importDefault(require("path")); +function getAbsolutePath(relativePath) { + // Use process.cwd() which should be the project root during test execution + return path_2.default.resolve(process.cwd(), 'test/e2e/prompt-module', relativePath); +} +async function setupCommitlint(dir, ver) { + let packagePath, packageJsonPath, configPath; + switch (ver) { + case 9: + packagePath = getAbsolutePath('./data/commitlint_9/node_modules'); + packageJsonPath = getAbsolutePath('./data/commitlint_9/package.json'); + configPath = getAbsolutePath('./data/commitlint_9/commitlint.config.js'); + break; + case 18: + packagePath = getAbsolutePath('./data/commitlint_18/node_modules'); + packageJsonPath = getAbsolutePath('./data/commitlint_18/package.json'); + configPath = getAbsolutePath('./data/commitlint_18/commitlint.config.js'); + break; + case 19: + packagePath = getAbsolutePath('./data/commitlint_19/node_modules'); + packageJsonPath = getAbsolutePath('./data/commitlint_19/package.json'); + configPath = getAbsolutePath('./data/commitlint_19/commitlint.config.js'); + break; + } + await (0, cli_testing_library_1.render)('cp', ['-r', packagePath, '.'], { cwd: dir }); + await (0, cli_testing_library_1.render)('cp', [packageJsonPath, '.'], { cwd: dir }); + await (0, cli_testing_library_1.render)('cp', [configPath, '.'], { cwd: dir }); + await (0, utils_1.wait)(3000); // Avoid flakiness by waiting +} +describe('cli flow to run "oco commitlint force"', () => { + it('on commitlint@9 using CJS', async () => { + const { gitDir, cleanup } = await (0, utils_1.prepareEnvironment)(); + await setupCommitlint(gitDir, 9); + const npmList = await (0, cli_testing_library_1.render)('npm', ['list', '@commitlint/load'], { + cwd: gitDir + }); + expect(await npmList.findByText('@commitlint/load@9')).toBeInTheConsole(); + const { findByText } = await (0, cli_testing_library_1.render)(` + OCO_TEST_MOCK_TYPE='prompt-module-commitlint-config' \ + OCO_PROMPT_MODULE='@commitlint' \ + OCO_AI_PROVIDER='test' OCO_GITPUSH='true' \ + node ${(0, path_1.resolve)('./out/cli.cjs')} commitlint force \ + `, [], { cwd: gitDir }); + expect(await findByText('opencommit — configure @commitlint')).toBeInTheConsole(); + expect(await findByText('Read @commitlint configuration')).toBeInTheConsole(); + expect(await findByText('Generating consistency with given @commitlint rules')).toBeInTheConsole(); + expect(await findByText('Done - please review contents of')).toBeInTheConsole(); + await cleanup(); + }); + it('on commitlint@18 using CJS', async () => { + const { gitDir, cleanup } = await (0, utils_1.prepareEnvironment)(); + await setupCommitlint(gitDir, 18); + const npmList = await (0, cli_testing_library_1.render)('npm', ['list', '@commitlint/load'], { + cwd: gitDir + }); + expect(await npmList.findByText('@commitlint/load@18')).toBeInTheConsole(); + const { findByText } = await (0, cli_testing_library_1.render)(` + OCO_TEST_MOCK_TYPE='prompt-module-commitlint-config' \ + OCO_PROMPT_MODULE='@commitlint' \ + OCO_AI_PROVIDER='test' OCO_GITPUSH='true' \ + node ${(0, path_1.resolve)('./out/cli.cjs')} commitlint force \ + `, [], { cwd: gitDir }); + expect(await findByText('opencommit — configure @commitlint')).toBeInTheConsole(); + expect(await findByText('Read @commitlint configuration')).toBeInTheConsole(); + expect(await findByText('Generating consistency with given @commitlint rules')).toBeInTheConsole(); + expect(await findByText('Done - please review contents of')).toBeInTheConsole(); + await cleanup(); + }); + it('on commitlint@19 using ESM', async () => { + const { gitDir, cleanup } = await (0, utils_1.prepareEnvironment)(); + await setupCommitlint(gitDir, 19); + const npmList = await (0, cli_testing_library_1.render)('npm', ['list', '@commitlint/load'], { + cwd: gitDir + }); + expect(await npmList.findByText('@commitlint/load@19')).toBeInTheConsole(); + const { findByText } = await (0, cli_testing_library_1.render)(` + OCO_TEST_MOCK_TYPE='prompt-module-commitlint-config' \ + OCO_PROMPT_MODULE='@commitlint' \ + OCO_AI_PROVIDER='test' OCO_GITPUSH='true' \ + node ${(0, path_1.resolve)('./out/cli.cjs')} commitlint force \ + `, [], { cwd: gitDir }); + expect(await findByText('opencommit — configure @commitlint')).toBeInTheConsole(); + expect(await findByText('Read @commitlint configuration')).toBeInTheConsole(); + expect(await findByText('Generating consistency with given @commitlint rules')).toBeInTheConsole(); + expect(await findByText('Done - please review contents of')).toBeInTheConsole(); + await cleanup(); + }); +}); +describe('cli flow to generate commit message using @commitlint prompt-module', () => { + it('on commitlint@19 using ESM', async () => { + const { gitDir, cleanup } = await (0, utils_1.prepareEnvironment)(); + // Setup commitlint@19 + await setupCommitlint(gitDir, 19); + const npmList = await (0, cli_testing_library_1.render)('npm', ['list', '@commitlint/load'], { + cwd: gitDir + }); + expect(await npmList.findByText('@commitlint/load@19')).toBeInTheConsole(); + // Run `oco commitlint force` + const commitlintForce = await (0, cli_testing_library_1.render)(` + OCO_TEST_MOCK_TYPE='prompt-module-commitlint-config' \ + OCO_PROMPT_MODULE='@commitlint' \ + OCO_AI_PROVIDER='test' OCO_GITPUSH='true' \ + node ${(0, path_1.resolve)('./out/cli.cjs')} commitlint force \ + `, [], { cwd: gitDir }); + expect(await commitlintForce.findByText('Done - please review contents of')).toBeInTheConsole(); + // Run `oco commitlint get` + const commitlintGet = await (0, cli_testing_library_1.render)(` + OCO_TEST_MOCK_TYPE='prompt-module-commitlint-config' \ + OCO_PROMPT_MODULE='@commitlint' \ + OCO_AI_PROVIDER='test' OCO_GITPUSH='true' \ + node ${(0, path_1.resolve)('./out/cli.cjs')} commitlint get \ + `, [], { cwd: gitDir }); + expect(await commitlintGet.findByText('consistency')).toBeInTheConsole(); + // Run 'oco' using .opencommit-commitlint + await (0, cli_testing_library_1.render)('echo', [`'console.log("Hello World");' > index.ts`], { + cwd: gitDir + }); + await (0, cli_testing_library_1.render)('git', ['add index.ts'], { cwd: gitDir }); + const oco = await (0, cli_testing_library_1.render)(` + OCO_TEST_MOCK_TYPE='commit-message' \ + OCO_PROMPT_MODULE='@commitlint' \ + OCO_AI_PROVIDER='test' OCO_GITPUSH='true' \ + node ${(0, path_1.resolve)('./out/cli.cjs')} \ + `, [], { cwd: gitDir }); + expect(await oco.findByText('Generating the commit message')).toBeInTheConsole(); + expect(await oco.findByText('Confirm the commit message?')).toBeInTheConsole(); + oco.userEvent.keyboard('[Enter]'); + expect(await oco.findByText('Do you want to run `git push`?')).toBeInTheConsole(); + oco.userEvent.keyboard('[Enter]'); + expect(await oco.findByText('Successfully pushed all commits to origin')).toBeInTheConsole(); + await cleanup(); + }); +}); diff --git a/test/e2e/utils.js b/test/e2e/utils.js new file mode 100644 index 0000000..30739c3 --- /dev/null +++ b/test/e2e/utils.js @@ -0,0 +1,39 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.wait = exports.prepareTempDir = exports.prepareEnvironment = void 0; +const path_1 = __importDefault(require("path")); +const fs_1 = require("fs"); +const util_1 = require("util"); +const os_1 = require("os"); +const child_process_1 = require("child_process"); +const fsMakeTempDir = (0, util_1.promisify)(fs_1.mkdtemp); +const fsExec = (0, util_1.promisify)(child_process_1.exec); +const fsRemove = (0, util_1.promisify)(fs_1.rm); +/** + * Prepare the environment for the test + * Create a temporary git repository in the temp directory + */ +const prepareEnvironment = async () => { + const tempDir = await (0, exports.prepareTempDir)(); + // Create a remote git repository int the temp directory. This is necessary to execute the `git push` command + await fsExec('git init --bare remote.git', { cwd: tempDir }); + await fsExec('git clone remote.git test', { cwd: tempDir }); + const gitDir = path_1.default.resolve(tempDir, 'test'); + const cleanup = async () => { + return fsRemove(tempDir, { recursive: true }); + }; + return { + gitDir, + cleanup, + }; +}; +exports.prepareEnvironment = prepareEnvironment; +const prepareTempDir = async () => { + return await fsMakeTempDir(path_1.default.join((0, os_1.tmpdir)(), 'opencommit-test-')); +}; +exports.prepareTempDir = prepareTempDir; +const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms)); +exports.wait = wait; diff --git a/test/jest-setup.js b/test/jest-setup.js new file mode 100644 index 0000000..f154aa5 --- /dev/null +++ b/test/jest-setup.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const globals_1 = require("@jest/globals"); +require("cli-testing-library/extend-expect"); +const cli_testing_library_1 = require("cli-testing-library"); +// Make Jest available globally +global.jest = globals_1.jest; +/** + * Adjusted the wait time for waitFor/findByText to 2000ms, because the default 1000ms makes the test results flaky + */ +(0, cli_testing_library_1.configure)({ asyncUtilTimeout: 2000 }); diff --git a/test/unit/config.test.js b/test/unit/config.test.js new file mode 100644 index 0000000..e6aa8b2 --- /dev/null +++ b/test/unit/config.test.js @@ -0,0 +1,248 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const fs_1 = require("fs"); +const config_1 = require("../../src/commands/config"); +const utils_1 = require("./utils"); +describe('config', () => { + const originalEnv = { ...process.env }; + let globalConfigFile; + let envConfigFile; + function resetEnv(env) { + Object.keys(process.env).forEach((key) => { + if (!(key in env)) { + delete process.env[key]; + } + else { + process.env[key] = env[key]; + } + }); + } + beforeEach(async () => { + resetEnv(originalEnv); + if (globalConfigFile) + await globalConfigFile.cleanup(); + if (envConfigFile) + await envConfigFile.cleanup(); + }); + afterEach(async () => { + if (globalConfigFile) + await globalConfigFile.cleanup(); + if (envConfigFile) + await envConfigFile.cleanup(); + }); + afterAll(() => { + resetEnv(originalEnv); + }); + const generateConfig = async (fileName, content) => { + const fileContent = Object.entries(content) + .map(([key, value]) => `${key}="${value}"`) + .join('\n'); + return await (0, utils_1.prepareFile)(fileName, fileContent); + }; + describe('getConfig', () => { + it('should prioritize local .env over global .opencommit config', async () => { + globalConfigFile = await generateConfig('.opencommit', { + OCO_API_KEY: 'global-key', + OCO_MODEL: 'gpt-3.5-turbo', + OCO_LANGUAGE: 'en' + }); + envConfigFile = await generateConfig('.env', { + OCO_API_KEY: 'local-key', + OCO_LANGUAGE: 'fr' + }); + const config = (0, config_1.getConfig)({ + globalPath: globalConfigFile.filePath, + envPath: envConfigFile.filePath + }); + expect(config).not.toEqual(null); + expect(config.OCO_API_KEY).toEqual('local-key'); + expect(config.OCO_MODEL).toEqual('gpt-3.5-turbo'); + expect(config.OCO_LANGUAGE).toEqual('fr'); + }); + it('should fallback to global config when local config is not set', async () => { + globalConfigFile = await generateConfig('.opencommit', { + OCO_API_KEY: 'global-key', + OCO_MODEL: 'gpt-4', + OCO_LANGUAGE: 'de', + OCO_DESCRIPTION: 'true' + }); + envConfigFile = await generateConfig('.env', { + OCO_API_URL: 'local-api-url' + }); + const config = (0, config_1.getConfig)({ + globalPath: globalConfigFile.filePath, + envPath: envConfigFile.filePath + }); + expect(config).not.toEqual(null); + expect(config.OCO_API_KEY).toEqual('global-key'); + expect(config.OCO_API_URL).toEqual('local-api-url'); + expect(config.OCO_MODEL).toEqual('gpt-4'); + expect(config.OCO_LANGUAGE).toEqual('de'); + expect(config.OCO_DESCRIPTION).toEqual(true); + }); + it('should handle boolean and numeric values correctly', async () => { + globalConfigFile = await generateConfig('.opencommit', { + OCO_TOKENS_MAX_INPUT: '4096', + OCO_TOKENS_MAX_OUTPUT: '500', + OCO_GITPUSH: 'true' + }); + envConfigFile = await generateConfig('.env', { + OCO_TOKENS_MAX_INPUT: '8192', + OCO_ONE_LINE_COMMIT: 'false', + OCO_OMIT_SCOPE: 'true' + }); + const config = (0, config_1.getConfig)({ + globalPath: globalConfigFile.filePath, + envPath: envConfigFile.filePath + }); + expect(config).not.toEqual(null); + expect(config.OCO_TOKENS_MAX_INPUT).toEqual(8192); + expect(config.OCO_TOKENS_MAX_OUTPUT).toEqual(500); + expect(config.OCO_GITPUSH).toEqual(true); + expect(config.OCO_ONE_LINE_COMMIT).toEqual(false); + expect(config.OCO_OMIT_SCOPE).toEqual(true); + }); + it('should handle custom HTTP headers correctly', async () => { + globalConfigFile = await generateConfig('.opencommit', { + OCO_API_CUSTOM_HEADERS: '{"X-Global-Header": "global-value"}' + }); + envConfigFile = await generateConfig('.env', { + OCO_API_CUSTOM_HEADERS: '{"Authorization": "Bearer token123", "X-Custom-Header": "test-value"}' + }); + const config = (0, config_1.getConfig)({ + globalPath: globalConfigFile.filePath, + envPath: envConfigFile.filePath + }); + expect(config).not.toEqual(null); + expect(config.OCO_API_CUSTOM_HEADERS).toEqual({ "Authorization": "Bearer token123", "X-Custom-Header": "test-value" }); + // No need to parse JSON again since it's already an object + const parsedHeaders = config.OCO_API_CUSTOM_HEADERS; + expect(parsedHeaders).toHaveProperty('Authorization', 'Bearer token123'); + expect(parsedHeaders).toHaveProperty('X-Custom-Header', 'test-value'); + expect(parsedHeaders).not.toHaveProperty('X-Global-Header'); + }); + it('should handle empty local config correctly', async () => { + globalConfigFile = await generateConfig('.opencommit', { + OCO_API_KEY: 'global-key', + OCO_MODEL: 'gpt-4', + OCO_LANGUAGE: 'es' + }); + envConfigFile = await generateConfig('.env', {}); + const config = (0, config_1.getConfig)({ + globalPath: globalConfigFile.filePath, + envPath: envConfigFile.filePath + }); + expect(config).not.toEqual(null); + expect(config.OCO_API_KEY).toEqual('global-key'); + expect(config.OCO_MODEL).toEqual('gpt-4'); + expect(config.OCO_LANGUAGE).toEqual('es'); + }); + it('should override global config with null values in local .env', async () => { + globalConfigFile = await generateConfig('.opencommit', { + OCO_API_KEY: 'global-key', + OCO_MODEL: 'gpt-4', + OCO_LANGUAGE: 'es' + }); + envConfigFile = await generateConfig('.env', { + OCO_API_KEY: 'null' + }); + const config = (0, config_1.getConfig)({ + globalPath: globalConfigFile.filePath, + envPath: envConfigFile.filePath + }); + expect(config).not.toEqual(null); + expect(config.OCO_API_KEY).toEqual(null); + }); + it('should handle empty global config', async () => { + globalConfigFile = await generateConfig('.opencommit', {}); + envConfigFile = await generateConfig('.env', {}); + const config = (0, config_1.getConfig)({ + globalPath: globalConfigFile.filePath, + envPath: envConfigFile.filePath + }); + expect(config).not.toEqual(null); + expect(config.OCO_API_KEY).toEqual(undefined); + }); + }); + describe('setConfig', () => { + beforeEach(async () => { + // we create and delete the file to have the parent directory, but not the file, to test the creation of the file + globalConfigFile = await generateConfig('.opencommit', {}); + (0, fs_1.rmSync)(globalConfigFile.filePath); + }); + it('should create .opencommit file with DEFAULT CONFIG if it does not exist on first setConfig run', async () => { + const isGlobalConfigFileExist = (0, fs_1.existsSync)(globalConfigFile.filePath); + expect(isGlobalConfigFileExist).toBe(false); + await (0, config_1.setConfig)([[config_1.CONFIG_KEYS.OCO_API_KEY, 'persisted-key_1']], globalConfigFile.filePath); + const fileContent = (0, fs_1.readFileSync)(globalConfigFile.filePath, 'utf8'); + expect(fileContent).toContain('OCO_API_KEY=persisted-key_1'); + Object.entries(config_1.DEFAULT_CONFIG).forEach(([key, value]) => { + expect(fileContent).toContain(`${key}=${value}`); + }); + }); + it('should set new config values', async () => { + globalConfigFile = await generateConfig('.opencommit', {}); + await (0, config_1.setConfig)([ + [config_1.CONFIG_KEYS.OCO_API_KEY, 'new-key'], + [config_1.CONFIG_KEYS.OCO_MODEL, 'gpt-4'] + ], globalConfigFile.filePath); + const config = (0, config_1.getConfig)({ + globalPath: globalConfigFile.filePath + }); + expect(config.OCO_API_KEY).toEqual('new-key'); + expect(config.OCO_MODEL).toEqual('gpt-4'); + }); + it('should update existing config values', async () => { + globalConfigFile = await generateConfig('.opencommit', { + OCO_API_KEY: 'initial-key' + }); + await (0, config_1.setConfig)([[config_1.CONFIG_KEYS.OCO_API_KEY, 'updated-key']], globalConfigFile.filePath); + const config = (0, config_1.getConfig)({ + globalPath: globalConfigFile.filePath + }); + expect(config.OCO_API_KEY).toEqual('updated-key'); + }); + it('should handle boolean and numeric values correctly', async () => { + globalConfigFile = await generateConfig('.opencommit', {}); + await (0, config_1.setConfig)([ + [config_1.CONFIG_KEYS.OCO_TOKENS_MAX_INPUT, '8192'], + [config_1.CONFIG_KEYS.OCO_DESCRIPTION, 'true'], + [config_1.CONFIG_KEYS.OCO_ONE_LINE_COMMIT, 'false'] + ], globalConfigFile.filePath); + const config = (0, config_1.getConfig)({ + globalPath: globalConfigFile.filePath + }); + expect(config.OCO_TOKENS_MAX_INPUT).toEqual(8192); + expect(config.OCO_DESCRIPTION).toEqual(true); + expect(config.OCO_ONE_LINE_COMMIT).toEqual(false); + }); + it('should throw an error for unsupported config keys', async () => { + globalConfigFile = await generateConfig('.opencommit', {}); + try { + await (0, config_1.setConfig)([['UNSUPPORTED_KEY', 'value']], globalConfigFile.filePath); + throw new Error('NEVER_REACHED'); + } + catch (error) { + expect(error.message).toContain('Unsupported config key: UNSUPPORTED_KEY'); + expect(error.message).not.toContain('NEVER_REACHED'); + } + }); + it('should persist changes to the config file', async () => { + const isGlobalConfigFileExist = (0, fs_1.existsSync)(globalConfigFile.filePath); + expect(isGlobalConfigFileExist).toBe(false); + await (0, config_1.setConfig)([[config_1.CONFIG_KEYS.OCO_API_KEY, 'persisted-key']], globalConfigFile.filePath); + const fileContent = (0, fs_1.readFileSync)(globalConfigFile.filePath, 'utf8'); + expect(fileContent).toContain('OCO_API_KEY=persisted-key'); + }); + it('should set multiple configs in a row and keep the changes', async () => { + const isGlobalConfigFileExist = (0, fs_1.existsSync)(globalConfigFile.filePath); + expect(isGlobalConfigFileExist).toBe(false); + await (0, config_1.setConfig)([[config_1.CONFIG_KEYS.OCO_API_KEY, 'persisted-key']], globalConfigFile.filePath); + const fileContent1 = (0, fs_1.readFileSync)(globalConfigFile.filePath, 'utf8'); + expect(fileContent1).toContain('OCO_API_KEY=persisted-key'); + await (0, config_1.setConfig)([[config_1.CONFIG_KEYS.OCO_MODEL, 'gpt-4']], globalConfigFile.filePath); + const fileContent2 = (0, fs_1.readFileSync)(globalConfigFile.filePath, 'utf8'); + expect(fileContent2).toContain('OCO_MODEL=gpt-4'); + }); + }); +}); diff --git a/test/unit/gemini.test.js b/test/unit/gemini.test.js new file mode 100644 index 0000000..f5e7bea --- /dev/null +++ b/test/unit/gemini.test.js @@ -0,0 +1,69 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const gemini_1 = require("../../src/engine/gemini"); +const generative_ai_1 = require("@google/generative-ai"); +const config_1 = require("../../src/commands/config"); +describe('Gemini', () => { + let gemini; + let mockConfig; + let mockGoogleGenerativeAi; + let mockGenerativeModel; + let mockExit; + const noop = (...args) => { }; + const mockGemini = () => { + mockConfig = (0, config_1.getConfig)(); + gemini = new gemini_1.GeminiEngine({ + apiKey: mockConfig.OCO_API_KEY, + model: mockConfig.OCO_MODEL + }); + }; + const oldEnv = process.env; + beforeEach(() => { + jest.resetModules(); + process.env = { ...oldEnv }; + jest.mock('@google/generative-ai'); + jest.mock('../src/commands/config'); + jest.mock('@clack/prompts', () => ({ + intro: jest.fn(), + outro: jest.fn() + })); + mockExit = jest.spyOn(process, 'exit').mockImplementation(); + mockConfig = (0, config_1.getConfig)(); + mockConfig.OCO_AI_PROVIDER = config_1.OCO_AI_PROVIDER_ENUM.GEMINI; + mockConfig.OCO_API_KEY = 'mock-api-key'; + mockConfig.OCO_MODEL = 'gemini-1.5-flash'; + mockGoogleGenerativeAi = new generative_ai_1.GoogleGenerativeAI(mockConfig.OCO_API_KEY); + mockGenerativeModel = mockGoogleGenerativeAi.getGenerativeModel({ + model: mockConfig.OCO_MODEL + }); + }); + afterEach(() => { + gemini = undefined; + }); + afterAll(() => { + mockExit.mockRestore(); + process.env = oldEnv; + }); + it.skip('should exit process if OCO_GEMINI_API_KEY is not set and command is not config', () => { + process.env.OCO_GEMINI_API_KEY = undefined; + process.env.OCO_AI_PROVIDER = 'gemini'; + mockGemini(); + expect(mockExit).toHaveBeenCalledWith(1); + }); + it('should generate commit message', async () => { + const mockGenerateContent = jest + .fn() + .mockResolvedValue({ response: { text: () => 'generated content' } }); + mockGenerativeModel.generateContent = mockGenerateContent; + mockGemini(); + const messages = [ + { role: 'system', content: 'system message' }, + { role: 'assistant', content: 'assistant message' } + ]; + jest + .spyOn(gemini, 'generateCommitMessage') + .mockImplementation(async () => 'generated content'); + const result = await gemini.generateCommitMessage(messages); + expect(result).toEqual('generated content'); + }); +}); diff --git a/test/unit/removeContentTags.test.js b/test/unit/removeContentTags.test.js new file mode 100644 index 0000000..d7ecb9b --- /dev/null +++ b/test/unit/removeContentTags.test.js @@ -0,0 +1,50 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const removeContentTags_1 = require("../../src/utils/removeContentTags"); +describe('removeContentTags', () => { + it('should remove content wrapped in specified tags', () => { + const content = 'This is something to hide visible content'; + const result = (0, removeContentTags_1.removeContentTags)(content, 'think'); + expect(result).toBe('This is visible content'); + }); + it('should handle multiple tag occurrences', () => { + const content = 'hidden visible also hidden text'; + const result = (0, removeContentTags_1.removeContentTags)(content, 'think'); + expect(result).toBe('visible text'); + }); + it('should handle multiline content within tags', () => { + const content = 'Start hidden\nover multiple\nlines End'; + const result = (0, removeContentTags_1.removeContentTags)(content, 'think'); + expect(result).toBe('Start End'); + }); + it('should return content as is when tag is not found', () => { + const content = 'Content without any tags'; + const result = (0, removeContentTags_1.removeContentTags)(content, 'think'); + expect(result).toBe('Content without any tags'); + }); + it('should work with different tag names', () => { + const content = 'This is something to hide visible content'; + const result = (0, removeContentTags_1.removeContentTags)(content, 'custom'); + expect(result).toBe('This is visible content'); + }); + it('should handle null content', () => { + const content = null; + const result = (0, removeContentTags_1.removeContentTags)(content, 'think'); + expect(result).toBe(null); + }); + it('should handle undefined content', () => { + const content = undefined; + const result = (0, removeContentTags_1.removeContentTags)(content, 'think'); + expect(result).toBe(undefined); + }); + it('should trim the result', () => { + const content = ' hidden visible '; + const result = (0, removeContentTags_1.removeContentTags)(content, 'think'); + expect(result).toBe('visible'); + }); + it('should handle nested tags correctly', () => { + const content = 'Outside Inside Nested End'; + const result = (0, removeContentTags_1.removeContentTags)(content, 'think'); + expect(result).toBe('Outside End'); + }); +}); diff --git a/test/unit/utils.js b/test/unit/utils.js new file mode 100644 index 0000000..c8f1649 --- /dev/null +++ b/test/unit/utils.js @@ -0,0 +1,31 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.prepareFile = void 0; +const fs_1 = require("fs"); +const os_1 = require("os"); +const path_1 = __importDefault(require("path")); +const util_1 = require("util"); +const fsMakeTempDir = (0, util_1.promisify)(fs_1.mkdtemp); +const fsRemove = (0, util_1.promisify)(fs_1.rm); +const fsWriteFile = (0, util_1.promisify)(fs_1.writeFile); +/** + * Prepare tmp file for the test + */ +async function prepareFile(fileName, content) { + const tempDir = await fsMakeTempDir(path_1.default.join((0, os_1.tmpdir)(), 'opencommit-test-')); + const filePath = path_1.default.resolve(tempDir, fileName); + await fsWriteFile(filePath, content); + const cleanup = async () => { + if ((0, fs_1.existsSync)(tempDir)) { + await fsRemove(tempDir, { recursive: true }); + } + }; + return { + filePath, + cleanup + }; +} +exports.prepareFile = prepareFile; diff --git a/tsconfig.action.json b/tsconfig.action.json new file mode 100644 index 0000000..60681ce --- /dev/null +++ b/tsconfig.action.json @@ -0,0 +1,22 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./out", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "target": "ES2020", + "strict": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "allowImportingTsExtensions": true + }, + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "node_modules", + "test", + "out" + ] +}