From 9b238f3c6c8a149446d17fadc9f00ad408f6086a Mon Sep 17 00:00:00 2001 From: Jack Sharkey Date: Sat, 27 Dec 2025 18:38:14 +0900 Subject: [PATCH 1/8] feat: add monorepo support with configurable paths and prerelease types - Add new action inputs: working-directory, version-files, publish-packages, prerelease-type, base-branch - Support updating multiple package.json files when creating release PRs - Support configurable prerelease types (e.g., beta instead of canary) - Support monorepo subdirectories via working-directory input - Backwards compatible: existing repos continue to work with defaults --- action.yml | 14 ++ packages/action/out/174.index.js | 206 ++++++++++++++------- packages/action/out/212.index.js | 89 +++++++-- packages/action/out/587.index.js | 110 ++++++++--- packages/action/out/607.index.js | 178 +++++++++++++----- packages/action/out/767.index.js | 18 +- packages/action/out/967.index.js | 12 +- packages/action/src/check/index.ts | 52 +++++- packages/action/src/context.ts | 17 ++ packages/action/src/release-pull/create.ts | 96 +++++++--- packages/action/src/release-pull/shared.ts | 7 +- packages/action/src/release-pull/sync.ts | 19 +- packages/action/src/release-pull/type.ts | 68 ++++--- packages/action/src/util/is-canary.ts | 12 +- 14 files changed, 671 insertions(+), 227 deletions(-) diff --git a/action.yml b/action.yml index de7702a..ab350c1 100644 --- a/action.yml +++ b/action.yml @@ -17,3 +17,17 @@ inputs: description: "Indicates if the same workflow published a new release to npm, required for 'sync' action" version: description: "The current verison of the package. Required for 'release'" + working-directory: + description: "Subdirectory to operate in (for monorepos). Paths are relative to this directory." + default: "." + version-files: + description: "JSON array of package.json paths to update when creating release PRs. All files will be updated to the same version." + default: '["package.json"]' + publish-packages: + description: "JSON array of package paths to check for publishing. If not set, scans packages/* directory." + prerelease-type: + description: "Prerelease identifier to use (e.g., 'canary', 'beta')" + default: "canary" + base-branch: + description: "Base branch for PRs and releases" + default: "main" diff --git a/packages/action/out/174.index.js b/packages/action/out/174.index.js index c05bdd7..b3fac05 100644 --- a/packages/action/out/174.index.js +++ b/packages/action/out/174.index.js @@ -15,8 +15,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var semver_functions_inc__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(semver_functions_inc__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _context__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7501); /* harmony import */ var _util_get_message__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(767); -/* harmony import */ var _util_is_action_user__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1514); -/* harmony import */ var _shared__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8089); +/* harmony import */ var _util_is_action_user__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1514); +/* harmony import */ var _shared__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8089); function _array_like_to_array(arr, len) { if (len == null || len > arr.length) len = arr.length; for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i]; @@ -251,12 +251,14 @@ function _ts_generator(thisArg, body) { var runAction = function() { return _async_to_generator(function() { - var stale, staleCanary, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, pulls, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, pull, err, _ref, canaryPull, fullPull; + var fullReleaseTitle, prereleaseTitle, stale, stalePrerelease, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, pulls, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, pull, err, _ref, prereleasePull, fullPull; return _ts_generator(this, function(_state) { switch(_state.label){ case 0: + fullReleaseTitle = (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getFullReleaseTitle */ .n)(); + prereleaseTitle = (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getPrereleaseTitle */ .e)(); stale = []; - staleCanary = []; + stalePrerelease = []; _iteratorAbruptCompletion = false, _didIteratorError = false; _state.label = 1; case 1: @@ -291,9 +293,9 @@ var runAction = function() { try { for(_iterator1 = pulls[Symbol.iterator](); !(_iteratorNormalCompletion = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion = true){ pull = _step1.value; - if ((0,_util_is_action_user__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(pull.user)) { - if (_shared__WEBPACK_IMPORTED_MODULE_4__/* .fullReleaseTitle */ .o === pull.title) stale.push(pull); - else if (_shared__WEBPACK_IMPORTED_MODULE_4__/* .canaryReleaseTitle */ .G === pull.title) staleCanary.push(pull); + if ((0,_util_is_action_user__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z)(pull.user)) { + if (fullReleaseTitle === pull.title) stale.push(pull); + else if (prereleaseTitle === pull.title) stalePrerelease.push(pull); } } } catch (err) { @@ -368,7 +370,7 @@ var runAction = function() { // close stale PRs and delete the branches return [ 4, - Promise.all(_to_consumable_array(stale).concat(_to_consumable_array(staleCanary)).map(function(stalePull) { + Promise.all(_to_consumable_array(stale).concat(_to_consumable_array(stalePrerelease)).map(function(stalePull) { return _async_to_generator(function() { return _ts_generator(this, function(_state) { switch(_state.label){ @@ -415,13 +417,13 @@ var runAction = function() { _ref = _sliced_to_array.apply(void 0, [ _state.sent(), 2 - ]), canaryPull = _ref[0], fullPull = _ref[1]; + ]), prereleasePull = _ref[0], fullPull = _ref[1]; // add comments to closed PRs that link to the newly created PRs return [ 4, Promise.all([ - Promise.all(staleCanary.map(function(pull) { - return addCommentToClosed(pull.number, canaryPull.number); + Promise.all(stalePrerelease.map(function(pull) { + return addCommentToClosed(pull.number, prereleasePull.number); })), Promise.all(stale.map(function(pull) { return addCommentToClosed(pull.number, fullPull.number); @@ -466,18 +468,20 @@ var pull_labels = [ ]; var createPull = function(prerelease) { return _async_to_generator(function() { - var title, releaseLabel, _ref, content, packageJson, newVersion, _ref1, _ref_data, sha, shortSha, branch, message, _ref2, pull, err, e; + var title, releaseLabel, primaryVersionFile, _ref, content, packageJson, newVersion, _ref1, _ref_data, sha, shortSha, branch, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, versionFile, filePath, _ref2, fileContent, filePackageJson, err, message, _ref3, pull, _$err, e; return _ts_generator(this, function(_state) { switch(_state.label){ case 0: - title = prerelease ? _shared__WEBPACK_IMPORTED_MODULE_4__/* .canaryReleaseTitle */ .G : _shared__WEBPACK_IMPORTED_MODULE_4__/* .fullReleaseTitle */ .o; - releaseLabel = prerelease ? 'releases: canary' : 'releases: patch'; + title = prerelease ? (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getPrereleaseTitle */ .e)() : (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getFullReleaseTitle */ .n)(); + releaseLabel = prerelease ? "releases: ".concat(_context__WEBPACK_IMPORTED_MODULE_1__/* .prereleaseType */ .kD) : 'releases: patch'; + // Get the first version file to determine current version + primaryVersionFile = (0,_context__WEBPACK_IMPORTED_MODULE_1__/* .withWorkingDir */ .QV)(_context__WEBPACK_IMPORTED_MODULE_1__/* .versionFiles[0] */ .dm[0]); return [ 4, _context__WEBPACK_IMPORTED_MODULE_1__/* .octo.rest.repos.getContent */ .NR.rest.repos.getContent({ repo: _context__WEBPACK_IMPORTED_MODULE_1__/* .repo */ .O9, owner: _context__WEBPACK_IMPORTED_MODULE_1__/* .owner */ .cR, - path: 'package.json' + path: primaryVersionFile }) ]; case 1: @@ -485,24 +489,23 @@ var createPull = function(prerelease) { if (!('content' in content)) throw new Error('Could not get package.json contents'); packageJson = JSON.parse(Buffer.from(content.content, 'base64').toString()); if (!packageJson.version || packageJson.version.startsWith('0.0.0')) { - newVersion = prerelease ? '0.0.1-canary.0' : '0.0.1'; + newVersion = prerelease ? "0.0.1-".concat(_context__WEBPACK_IMPORTED_MODULE_1__/* .prereleaseType */ .kD, ".0") : '0.0.1'; } else { - newVersion = prerelease ? semver_functions_inc__WEBPACK_IMPORTED_MODULE_0___default()(packageJson.version, 'prerelease', 'canary') : semver_functions_inc__WEBPACK_IMPORTED_MODULE_0___default()(packageJson.version, 'patch'); + newVersion = prerelease ? semver_functions_inc__WEBPACK_IMPORTED_MODULE_0___default()(packageJson.version, 'prerelease', _context__WEBPACK_IMPORTED_MODULE_1__/* .prereleaseType */ .kD) : semver_functions_inc__WEBPACK_IMPORTED_MODULE_0___default()(packageJson.version, 'patch'); } if (!newVersion) throw new Error('Could not increase version'); - packageJson.version = newVersion; return [ 4, _context__WEBPACK_IMPORTED_MODULE_1__/* .octo.rest.git.getRef */ .NR.rest.git.getRef({ owner: _context__WEBPACK_IMPORTED_MODULE_1__/* .owner */ .cR, repo: _context__WEBPACK_IMPORTED_MODULE_1__/* .repo */ .O9, - ref: "heads/main" + ref: "heads/".concat(_context__WEBPACK_IMPORTED_MODULE_1__/* .baseBranch */ .a2) }) ]; case 2: _ref1 = _state.sent(), _ref_data = _ref1.data, sha = _ref_data.object.sha; shortSha = sha.slice(0, 6) + sha.slice(-6); - branch = prerelease ? "turbo-module/release-".concat(shortSha, "-canary") : "turbo-module/release-".concat(shortSha); + branch = prerelease ? "turbo-module/release-".concat(shortSha, "-").concat(_context__WEBPACK_IMPORTED_MODULE_1__/* .prereleaseType */ .kD) : "turbo-module/release-".concat(shortSha); return [ 4, _context__WEBPACK_IMPORTED_MODULE_1__/* .octo.rest.git.createRef */ .NR.rest.git.createRef({ @@ -514,25 +517,92 @@ var createPull = function(prerelease) { ]; case 3: _state.sent(); + _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined; + _state.label = 4; + case 4: + _state.trys.push([ + 4, + 10, + 11, + 12 + ]); + _iterator = _context__WEBPACK_IMPORTED_MODULE_1__/* .versionFiles */ .dm[Symbol.iterator](); + _state.label = 5; + case 5: + if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [ + 3, + 9 + ]; + versionFile = _step.value; + filePath = (0,_context__WEBPACK_IMPORTED_MODULE_1__/* .withWorkingDir */ .QV)(versionFile); + console.log("Updating version in ".concat(filePath, " to ").concat(newVersion)); + return [ + 4, + _context__WEBPACK_IMPORTED_MODULE_1__/* .octo.rest.repos.getContent */ .NR.rest.repos.getContent({ + repo: _context__WEBPACK_IMPORTED_MODULE_1__/* .repo */ .O9, + owner: _context__WEBPACK_IMPORTED_MODULE_1__/* .owner */ .cR, + path: filePath, + ref: branch + }) + ]; + case 6: + _ref2 = _state.sent(), fileContent = _ref2.data; + if (!('content' in fileContent)) throw new Error("Could not get ".concat(filePath, " contents")); + filePackageJson = JSON.parse(Buffer.from(fileContent.content, 'base64').toString()); + filePackageJson.version = newVersion; return [ 4, _context__WEBPACK_IMPORTED_MODULE_1__/* .octo.rest.repos.createOrUpdateFileContents */ .NR.rest.repos.createOrUpdateFileContents({ repo: _context__WEBPACK_IMPORTED_MODULE_1__/* .repo */ .O9, owner: _context__WEBPACK_IMPORTED_MODULE_1__/* .owner */ .cR, - path: 'package.json', - message: "release patch ".concat(packageJson.version), - content: Buffer.from(JSON.stringify(packageJson, null, 2) + '\n').toString('base64'), - sha: content.sha, + path: filePath, + message: "release: ".concat(newVersion), + content: Buffer.from(JSON.stringify(filePackageJson, null, 2) + '\n').toString('base64'), + sha: fileContent.sha, branch: branch }) ]; - case 4: + case 7: _state.sent(); + _state.label = 8; + case 8: + _iteratorNormalCompletion = true; + return [ + 3, + 5 + ]; + case 9: + return [ + 3, + 12 + ]; + case 10: + err = _state.sent(); + _didIteratorError = true; + _iteratorError = err; + return [ + 3, + 12 + ]; + case 11: + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally{ + if (_didIteratorError) { + throw _iteratorError; + } + } + return [ + 7 + ]; + case 12: return [ 4, (0,_util_get_message__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(prerelease) ]; - case 5: + case 13: message = _state.sent().message; return [ 4, @@ -542,25 +612,25 @@ var createPull = function(prerelease) { title: title, body: message, head: branch, - base: 'main' + base: _context__WEBPACK_IMPORTED_MODULE_1__/* .baseBranch */ .a2 }) ]; - case 6: - _ref2 = _state.sent(), pull = _ref2.data; - err = 0; - _state.label = 7; - case 7: - if (!(err < 5)) return [ + case 14: + _ref3 = _state.sent(), pull = _ref3.data; + _$err = 0; + _state.label = 15; + case 15: + if (!(_$err < 5)) return [ 3, - 13 + 21 ]; - _state.label = 8; - case 8: + _state.label = 16; + case 16: _state.trys.push([ - 8, - 10, + 16, + 18, , - 12 + 20 ]); return [ 4, @@ -573,34 +643,34 @@ var createPull = function(prerelease) { ]) }) ]; - case 9: + case 17: _state.sent(); return [ 2, pull ]; - case 10: + case 18: e = _state.sent(); console.error(e); - err++; + _$err++; return [ 4, new Promise(function(resolve) { return setTimeout(resolve, 300); }) ]; - case 11: + case 19: _state.sent(); return [ 3, - 12 + 20 ]; - case 12: + case 20: return [ 3, - 7 + 15 ]; - case 13: + case 21: throw new Error('Could not add labels to PR'); } }); @@ -615,11 +685,17 @@ var createPull = function(prerelease) { /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "G": () => (/* binding */ canaryReleaseTitle), -/* harmony export */ "o": () => (/* binding */ fullReleaseTitle) +/* harmony export */ "e": () => (/* binding */ getPrereleaseTitle), +/* harmony export */ "n": () => (/* binding */ getFullReleaseTitle) /* harmony export */ }); -var fullReleaseTitle = '(turbo-module): release next version'; -var canaryReleaseTitle = '(turbo-module): release next canary version'; +/* harmony import */ var _context__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7501); + +var getFullReleaseTitle = function() { + return '(turbo-module): release next version'; +}; +var getPrereleaseTitle = function() { + return "(turbo-module): release next ".concat(_context__WEBPACK_IMPORTED_MODULE_0__/* .prereleaseType */ .kD, " version"); +}; /***/ }), @@ -631,11 +707,11 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); -/* harmony import */ var _util_is_action_user__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1514); +/* harmony import */ var _util_is_action_user__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1514); /* harmony import */ var _context__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7501); /* harmony import */ var _util_get_message__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(767); -/* harmony import */ var _shared__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8089); -/* harmony import */ var _create__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3607); +/* harmony import */ var _shared__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8089); +/* harmony import */ var _create__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3607); function _async_iterator(iterable) { var method, async, sync, retry = 2; for("undefined" != typeof Symbol && (async = Symbol.asyncIterator, sync = Symbol.iterator); retry--;){ @@ -849,10 +925,12 @@ var syncPull = function(pull, prerelease) { }; var runAction = function() { return _async_to_generator(function() { - var full, canary, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, pulls, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, pull, err; + var fullReleaseTitle, prereleaseTitle, full, prerelease, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, pulls, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, pull, err; return _ts_generator(this, function(_state) { switch(_state.label){ case 0: + fullReleaseTitle = (0,_shared__WEBPACK_IMPORTED_MODULE_2__/* .getFullReleaseTitle */ .n)(); + prereleaseTitle = (0,_shared__WEBPACK_IMPORTED_MODULE_2__/* .getPrereleaseTitle */ .e)(); _iteratorAbruptCompletion = false, _didIteratorError = false; _state.label = 1; case 1: @@ -887,21 +965,21 @@ var runAction = function() { try { for(_iterator1 = pulls[Symbol.iterator](); !(_iteratorNormalCompletion = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion = true){ pull = _step1.value; - if ((0,_util_is_action_user__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(pull.user)) { + if ((0,_util_is_action_user__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z)(pull.user)) { switch(pull.title){ - case _shared__WEBPACK_IMPORTED_MODULE_4__/* .fullReleaseTitle */ .o: + case fullReleaseTitle: { if (!full) full = syncPull(pull, false); break; } - case _shared__WEBPACK_IMPORTED_MODULE_4__/* .canaryReleaseTitle */ .G: + case prereleaseTitle: { - if (!canary) canary = syncPull(pull, true); + if (!prerelease) prerelease = syncPull(pull, true); break; } } } - if (full && canary) break; + if (full && prerelease) break; } } catch (err) { _didIteratorError1 = true; @@ -917,7 +995,7 @@ var runAction = function() { } } } - if (full && canary) return [ + if (full && prerelease) return [ 3, 5 ]; @@ -976,13 +1054,13 @@ var runAction = function() { 7 ]; case 12: - if (!full) full = (0,_create__WEBPACK_IMPORTED_MODULE_2__.createPull)(false); - if (!canary) canary = (0,_create__WEBPACK_IMPORTED_MODULE_2__.createPull)(true); + if (!full) full = (0,_create__WEBPACK_IMPORTED_MODULE_3__.createPull)(false); + if (!prerelease) prerelease = (0,_create__WEBPACK_IMPORTED_MODULE_3__.createPull)(true); return [ 4, Promise.all([ full, - canary + prerelease ]) ]; case 13: diff --git a/packages/action/out/212.index.js b/packages/action/out/212.index.js index 767c4a4..c1611f7 100644 --- a/packages/action/out/212.index.js +++ b/packages/action/out/212.index.js @@ -554,6 +554,8 @@ var is_canary = __webpack_require__(9911); var semver = __webpack_require__(4122); // EXTERNAL MODULE: ./dist/util/get-file.js var get_file = __webpack_require__(2703); +// EXTERNAL MODULE: ./dist/context.js +var context = __webpack_require__(7501); ;// CONCATENATED MODULE: ./dist/check/index.js function check_array_like_to_array(arr, len) { if (len == null || len > arr.length) len = arr.length; @@ -753,7 +755,7 @@ function check_ts_generator(thisArg, body) { } function _templateObject() { var data = _tagged_template_literal([ - "\n npm view \n ", + "\n npm view\n ", "@", "\n " ]); @@ -777,10 +779,14 @@ function _templateObject1() { -var versionParserRegexp = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*@(\d+\.\d+\.\d+(?:-canary\.\d+)?)/; + +// Dynamic regex that supports the configured prerelease type +var createVersionParserRegexp = function() { + return new RegExp("^(@[a-z0-9-~][a-z0-9-._~]*/)?[a-z0-9-~][a-z0-9-._~]*@(\\d+\\.\\d+\\.\\d+(?:-".concat(context/* prereleaseType */.kD, "\\.\\d+)?)")); +}; var checkPackage = function(pkg, rootVersion) { return check_async_to_generator(function() { - var _ref, packageJson, log, _ref1, res, _ref2, currentVersion, _e, unused; + var _ref, packageJson, log, _ref1, res, versionParserRegexp, _ref2, currentVersion, _e, unused; return check_ts_generator(this, function(_state) { switch(_state.label){ case 0: @@ -821,7 +827,7 @@ var checkPackage = function(pkg, rootVersion) { ]); return [ 4, - bash(_templateObject1(), command(_templateObject(), packageJson.name, (0,is_canary/* default */.Z)(rootVersion) ? 'canary' : 'latest')) + bash(_templateObject1(), command(_templateObject(), packageJson.name, (0,is_canary/* default */.Z)(rootVersion) ? context/* prereleaseType */.kD : 'latest')) ]; case 3: _ref1 = _sliced_to_array.apply(void 0, [ @@ -829,6 +835,7 @@ var checkPackage = function(pkg, rootVersion) { 1 ]), res = _ref1[0]; if (!res) throw new Error('Ăšnexpected error'); + versionParserRegexp = createVersionParserRegexp(); _ref2 = _sliced_to_array(versionParserRegexp.exec(res.stdout.trim()) || [], 3), currentVersion = _ref2[2]; if (!currentVersion) throw new Error('Could not parse version from npm view response'); if ((0,semver.gt)(rootVersion, currentVersion)) { @@ -871,15 +878,45 @@ var checkPackage = function(pkg, rootVersion) { }; var checkPackages = function(rootVersion) { return check_async_to_generator(function() { - var folders; + var packagesDir, folders; return check_ts_generator(this, function(_state) { switch(_state.label){ case 0: + if (!(context/* publishPackages */.RP && context/* publishPackages.length */.RP.length > 0)) return [ + 3, + 2 + ]; + console.log('checking configured packages: ' + context/* publishPackages.join */.RP.join(', ')); return [ 4, - (0,get_file/* getFolder */.zZ)('packages') + Promise.all(context/* publishPackages.map */.RP.map(function(pkgPath) { + return check_async_to_generator(function() { + var fullPath, jsonPath; + return check_ts_generator(this, function(_state) { + fullPath = (0,context/* withWorkingDir */.QV)(pkgPath); + // If path doesn't end with package.json, append it + jsonPath = fullPath.endsWith('package.json') ? fullPath : "".concat(fullPath, "/package.json"); + return [ + 2, + checkPackage(jsonPath, rootVersion) + ]; + }); + })(); + })) ]; case 1: + return [ + 2, + _state.sent().filter(Boolean) + ]; + case 2: + // Otherwise, scan packages/* directory (legacy behavior) + packagesDir = (0,context/* withWorkingDir */.QV)('packages'); + return [ + 4, + (0,get_file/* getFolder */.zZ)(packagesDir) + ]; + case 3: folders = _state.sent(); console.log('checking ' + folders.map(function(param) { var path = param.path; @@ -899,7 +936,7 @@ var checkPackages = function(rootVersion) { })(); })) ]; - case 2: + case 4: return [ 2, _state.sent().filter(Boolean) @@ -916,17 +953,19 @@ var checkPackages = function(rootVersion) { * inteded to be ran as part of a workflow */ var canPublish = function() { return check_async_to_generator(function() { - var _ref, version, publishable; + var versionFilePath, _ref, version, publishable; return check_ts_generator(this, function(_state) { switch(_state.label){ case 0: + // Use the first version file as the source of truth for the version + versionFilePath = (0,context/* withWorkingDir */.QV)(context/* versionFiles.0 */.dm[0]); return [ 4, - (0,get_file/* getJsonFile */.n0)('package.json') + (0,get_file/* getJsonFile */.n0)(versionFilePath) ]; case 1: _ref = _state.sent(), version = _ref.content.version; - console.log('version:', version, 'is canary:', (0,is_canary/* default */.Z)(version)); + console.log('version:', version, "is ".concat(context/* prereleaseType */.kD, ":"), (0,is_canary/* default */.Z)(version)); if (!version.startsWith('0.0.0')) return [ 3, 2 @@ -970,12 +1009,17 @@ var checkPackages = function(rootVersion) { /* harmony export */ "NR": () => (/* binding */ octo), /* harmony export */ "O9": () => (/* binding */ repo), /* harmony export */ "PX": () => (/* binding */ target_issue), +/* harmony export */ "QV": () => (/* binding */ withWorkingDir), /* harmony export */ "RL": () => (/* binding */ target_comment), +/* harmony export */ "RP": () => (/* binding */ publishPackages), +/* harmony export */ "a2": () => (/* binding */ baseBranch), /* harmony export */ "cR": () => (/* binding */ owner), +/* harmony export */ "dm": () => (/* binding */ versionFiles), /* harmony export */ "hl": () => (/* binding */ commit_hash), +/* harmony export */ "kD": () => (/* binding */ prereleaseType), /* harmony export */ "sS": () => (/* binding */ initial_commit) /* harmony export */ }); -/* unused harmony export target_pull */ +/* unused harmony exports target_pull, workingDirectory */ /* harmony import */ var _actions_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1416); /* harmony import */ var _actions_core__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_actions_core__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _actions_github__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7036); @@ -989,6 +1033,17 @@ var octo = (0,_actions_github__WEBPACK_IMPORTED_MODULE_1__.getOctokit)(GITHUB_TO var _context_repo = _actions_github__WEBPACK_IMPORTED_MODULE_1__.context.repo, _context_payload = _actions_github__WEBPACK_IMPORTED_MODULE_1__.context.payload; var owner = _context_repo.owner, repo = _context_repo.repo, commit_hash = _actions_github__WEBPACK_IMPORTED_MODULE_1__.context.sha, target_issue = _context_payload.issue, target_comment = _context_payload.comment, target_pull = _context_payload.pull_request; var initial_commit = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('initial-commit'); +// Monorepo support configuration +var workingDirectory = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('working-directory') || '.'; +var versionFiles = JSON.parse((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('version-files') || '["package.json"]'); +var publishPackages = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('publish-packages') ? JSON.parse((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('publish-packages')) : undefined; +var prereleaseType = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('prerelease-type') || 'canary'; +var baseBranch = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('base-branch') || 'main'; +// Helper to join working directory with a path +var withWorkingDir = function(path) { + if (workingDirectory === '.') return path; + return "".concat(workingDirectory, "/").concat(path); +}; /***/ }), @@ -1228,12 +1283,20 @@ var getJsonFile = function(path, ref) { /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); -var isCanary = function(test) { - return /^\d+\.\d+\.\d+-canary\.\d+$/.test(test); +/* unused harmony export isPrerelease */ +/* harmony import */ var _context__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7501); + +// Check if version matches the configured prerelease type (e.g., canary, beta) +var isPrerelease = function(test) { + var pattern = new RegExp("^\\d+\\.\\d+\\.\\d+-".concat(_context__WEBPACK_IMPORTED_MODULE_0__/* .prereleaseType */ .kD, "\\.\\d+$")); + return pattern.test(test); }; +// Legacy export for backwards compatibility +var isCanary = isPrerelease; /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isCanary); + /***/ }) }; diff --git a/packages/action/out/587.index.js b/packages/action/out/587.index.js index 2bbc620..23aa697 100644 --- a/packages/action/out/587.index.js +++ b/packages/action/out/587.index.js @@ -10,12 +10,17 @@ exports.modules = { /* harmony export */ "NR": () => (/* binding */ octo), /* harmony export */ "O9": () => (/* binding */ repo), /* harmony export */ "PX": () => (/* binding */ target_issue), +/* harmony export */ "QV": () => (/* binding */ withWorkingDir), /* harmony export */ "RL": () => (/* binding */ target_comment), +/* harmony export */ "RP": () => (/* binding */ publishPackages), +/* harmony export */ "a2": () => (/* binding */ baseBranch), /* harmony export */ "cR": () => (/* binding */ owner), +/* harmony export */ "dm": () => (/* binding */ versionFiles), /* harmony export */ "hl": () => (/* binding */ commit_hash), +/* harmony export */ "kD": () => (/* binding */ prereleaseType), /* harmony export */ "sS": () => (/* binding */ initial_commit) /* harmony export */ }); -/* unused harmony export target_pull */ +/* unused harmony exports target_pull, workingDirectory */ /* harmony import */ var _actions_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1416); /* harmony import */ var _actions_core__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_actions_core__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _actions_github__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7036); @@ -29,6 +34,17 @@ var octo = (0,_actions_github__WEBPACK_IMPORTED_MODULE_1__.getOctokit)(GITHUB_TO var _context_repo = _actions_github__WEBPACK_IMPORTED_MODULE_1__.context.repo, _context_payload = _actions_github__WEBPACK_IMPORTED_MODULE_1__.context.payload; var owner = _context_repo.owner, repo = _context_repo.repo, commit_hash = _actions_github__WEBPACK_IMPORTED_MODULE_1__.context.sha, target_issue = _context_payload.issue, target_comment = _context_payload.comment, target_pull = _context_payload.pull_request; var initial_commit = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('initial-commit'); +// Monorepo support configuration +var workingDirectory = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('working-directory') || '.'; +var versionFiles = JSON.parse((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('version-files') || '["package.json"]'); +var publishPackages = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('publish-packages') ? JSON.parse((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('publish-packages')) : undefined; +var prereleaseType = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('prerelease-type') || 'canary'; +var baseBranch = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('base-branch') || 'main'; +// Helper to join working directory with a path +var withWorkingDir = function(path) { + if (workingDirectory === '.') return path; + return "".concat(workingDirectory, "/").concat(path); +}; /***/ }), @@ -462,7 +478,7 @@ var types = [ 'minor', 'major' ]; -var getPackageJson = function(ref) { +var getPackageJson = function(path, ref) { return type_async_to_generator(function() { var _ref, content; return type_ts_generator(this, function(_state) { @@ -473,7 +489,7 @@ var getPackageJson = function(ref) { context/* octo.rest.repos.getContent */.NR.rest.repos.getContent({ repo: context/* repo */.O9, owner: context/* owner */.cR, - path: 'package.json', + path: path, ref: ref }) ]; @@ -488,14 +504,14 @@ var getPackageJson = function(ref) { } ]; } - throw new Error('Could not load main package.json'); + throw new Error("Could not load ".concat(path)); } }); })(); }; var performUpdate = function(type) { return type_async_to_generator(function() { - var _ref, _ref_data, labels, _ref_data_head, branch, releaseTypeLabel, current_type, _ref1, mainPackageJson, _ref2, currentPackageJson, packageSha, currentVersion, newVersion, promises; + var _ref, _ref_data, labels, _ref_data_head, branch, releaseTypeLabel, current_type, primaryVersionFile, _ref1, mainPackageJson, currentVersion, newVersion, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, versionFile, filePath, _ref2, currentPackageJson, packageSha, err, promises; return type_ts_generator(this, function(_state) { switch(_state.label){ case 0: @@ -510,36 +526,52 @@ var performUpdate = function(type) { ]; case 1: _ref = _state.sent(), _ref_data = _ref.data, labels = _ref_data.labels, _ref_data_head = _ref_data.head, branch = _ref_data_head.ref; - /* await octo.rest.pulls.updateBranch({ - repo, - owner, - pull_number: target_issue.number, - }); */ releaseTypeLabel = labels.find(function(param) { + releaseTypeLabel = labels.find(function(param) { var name = param.name; return name.startsWith('releases: '); }); current_type = releaseTypeLabel === null || releaseTypeLabel === void 0 ? void 0 : releaseTypeLabel.name.replace('releases: ', ''); - if (current_type === 'canary' || type === current_type) return [ + // Skip if it's a prerelease PR or already the requested type + if (current_type === context/* prereleaseType */.kD || type === current_type) return [ 2 ]; + primaryVersionFile = (0,context/* withWorkingDir */.QV)(context/* versionFiles.0 */.dm[0]); return [ 4, - getPackageJson('main') + getPackageJson(primaryVersionFile, context/* baseBranch */.a2) ]; case 2: _ref1 = _state.sent(), mainPackageJson = _ref1.content; + currentVersion = mainPackageJson.version.startsWith('0.0.0') ? '0.0.0' : mainPackageJson.version; + newVersion = (0,semver.inc)(currentVersion, type); + if (!newVersion) throw new Error("Could not increase ".concat(type, " for ").concat(currentVersion)); + _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined; + _state.label = 3; + case 3: + _state.trys.push([ + 3, + 9, + 10, + 11 + ]); + _iterator = context/* versionFiles */.dm[Symbol.iterator](); + _state.label = 4; + case 4: + if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [ + 3, + 8 + ]; + versionFile = _step.value; + filePath = (0,context/* withWorkingDir */.QV)(versionFile); return [ 4, - getPackageJson(branch) + getPackageJson(filePath, branch) ]; - case 3: + case 5: _ref2 = _state.sent(), currentPackageJson = _ref2.content, packageSha = _ref2.sha; - currentVersion = mainPackageJson.version.startsWith('0.0.0') ? '0.0.0' : mainPackageJson.version; - newVersion = (0,semver.inc)(currentVersion, type); - if (!newVersion) throw new Error("Could not increase ".concat(type, " for ").concat(currentVersion)); if (!(currentPackageJson.version !== newVersion)) return [ 3, - 5 + 7 ]; currentPackageJson.version = newVersion; return [ @@ -547,17 +579,49 @@ var performUpdate = function(type) { context/* octo.rest.repos.createOrUpdateFileContents */.NR.rest.repos.createOrUpdateFileContents({ repo: context/* repo */.O9, owner: context/* owner */.cR, - path: 'package.json', + path: filePath, message: "release ".concat(type, " ").concat(newVersion), content: Buffer.from(JSON.stringify(currentPackageJson, null, 2) + '\n').toString('base64'), sha: packageSha, branch: branch }) ]; - case 4: + case 6: _state.sent(); - _state.label = 5; - case 5: + _state.label = 7; + case 7: + _iteratorNormalCompletion = true; + return [ + 3, + 4 + ]; + case 8: + return [ + 3, + 11 + ]; + case 9: + err = _state.sent(); + _didIteratorError = true; + _iteratorError = err; + return [ + 3, + 11 + ]; + case 10: + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally{ + if (_didIteratorError) { + throw _iteratorError; + } + } + return [ + 7 + ]; + case 11: promises = [ context/* octo.rest.issues.addLabels */.NR.rest.issues.addLabels({ repo: context/* repo */.O9, @@ -578,7 +642,7 @@ var performUpdate = function(type) { 4, Promise.all(promises) ]; - case 6: + case 12: _state.sent(); return [ 2 diff --git a/packages/action/out/607.index.js b/packages/action/out/607.index.js index 5e0441f..d712a17 100644 --- a/packages/action/out/607.index.js +++ b/packages/action/out/607.index.js @@ -15,8 +15,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var semver_functions_inc__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(semver_functions_inc__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _context__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7501); /* harmony import */ var _util_get_message__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(767); -/* harmony import */ var _util_is_action_user__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1514); -/* harmony import */ var _shared__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8089); +/* harmony import */ var _util_is_action_user__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1514); +/* harmony import */ var _shared__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8089); function _array_like_to_array(arr, len) { if (len == null || len > arr.length) len = arr.length; for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i]; @@ -251,12 +251,14 @@ function _ts_generator(thisArg, body) { var runAction = function() { return _async_to_generator(function() { - var stale, staleCanary, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, pulls, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, pull, err, _ref, canaryPull, fullPull; + var fullReleaseTitle, prereleaseTitle, stale, stalePrerelease, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, pulls, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, pull, err, _ref, prereleasePull, fullPull; return _ts_generator(this, function(_state) { switch(_state.label){ case 0: + fullReleaseTitle = (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getFullReleaseTitle */ .n)(); + prereleaseTitle = (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getPrereleaseTitle */ .e)(); stale = []; - staleCanary = []; + stalePrerelease = []; _iteratorAbruptCompletion = false, _didIteratorError = false; _state.label = 1; case 1: @@ -291,9 +293,9 @@ var runAction = function() { try { for(_iterator1 = pulls[Symbol.iterator](); !(_iteratorNormalCompletion = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion = true){ pull = _step1.value; - if ((0,_util_is_action_user__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(pull.user)) { - if (_shared__WEBPACK_IMPORTED_MODULE_4__/* .fullReleaseTitle */ .o === pull.title) stale.push(pull); - else if (_shared__WEBPACK_IMPORTED_MODULE_4__/* .canaryReleaseTitle */ .G === pull.title) staleCanary.push(pull); + if ((0,_util_is_action_user__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z)(pull.user)) { + if (fullReleaseTitle === pull.title) stale.push(pull); + else if (prereleaseTitle === pull.title) stalePrerelease.push(pull); } } } catch (err) { @@ -368,7 +370,7 @@ var runAction = function() { // close stale PRs and delete the branches return [ 4, - Promise.all(_to_consumable_array(stale).concat(_to_consumable_array(staleCanary)).map(function(stalePull) { + Promise.all(_to_consumable_array(stale).concat(_to_consumable_array(stalePrerelease)).map(function(stalePull) { return _async_to_generator(function() { return _ts_generator(this, function(_state) { switch(_state.label){ @@ -415,13 +417,13 @@ var runAction = function() { _ref = _sliced_to_array.apply(void 0, [ _state.sent(), 2 - ]), canaryPull = _ref[0], fullPull = _ref[1]; + ]), prereleasePull = _ref[0], fullPull = _ref[1]; // add comments to closed PRs that link to the newly created PRs return [ 4, Promise.all([ - Promise.all(staleCanary.map(function(pull) { - return addCommentToClosed(pull.number, canaryPull.number); + Promise.all(stalePrerelease.map(function(pull) { + return addCommentToClosed(pull.number, prereleasePull.number); })), Promise.all(stale.map(function(pull) { return addCommentToClosed(pull.number, fullPull.number); @@ -466,18 +468,20 @@ var pull_labels = [ ]; var createPull = function(prerelease) { return _async_to_generator(function() { - var title, releaseLabel, _ref, content, packageJson, newVersion, _ref1, _ref_data, sha, shortSha, branch, message, _ref2, pull, err, e; + var title, releaseLabel, primaryVersionFile, _ref, content, packageJson, newVersion, _ref1, _ref_data, sha, shortSha, branch, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, versionFile, filePath, _ref2, fileContent, filePackageJson, err, message, _ref3, pull, _$err, e; return _ts_generator(this, function(_state) { switch(_state.label){ case 0: - title = prerelease ? _shared__WEBPACK_IMPORTED_MODULE_4__/* .canaryReleaseTitle */ .G : _shared__WEBPACK_IMPORTED_MODULE_4__/* .fullReleaseTitle */ .o; - releaseLabel = prerelease ? 'releases: canary' : 'releases: patch'; + title = prerelease ? (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getPrereleaseTitle */ .e)() : (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getFullReleaseTitle */ .n)(); + releaseLabel = prerelease ? "releases: ".concat(_context__WEBPACK_IMPORTED_MODULE_1__/* .prereleaseType */ .kD) : 'releases: patch'; + // Get the first version file to determine current version + primaryVersionFile = (0,_context__WEBPACK_IMPORTED_MODULE_1__/* .withWorkingDir */ .QV)(_context__WEBPACK_IMPORTED_MODULE_1__/* .versionFiles[0] */ .dm[0]); return [ 4, _context__WEBPACK_IMPORTED_MODULE_1__/* .octo.rest.repos.getContent */ .NR.rest.repos.getContent({ repo: _context__WEBPACK_IMPORTED_MODULE_1__/* .repo */ .O9, owner: _context__WEBPACK_IMPORTED_MODULE_1__/* .owner */ .cR, - path: 'package.json' + path: primaryVersionFile }) ]; case 1: @@ -485,24 +489,23 @@ var createPull = function(prerelease) { if (!('content' in content)) throw new Error('Could not get package.json contents'); packageJson = JSON.parse(Buffer.from(content.content, 'base64').toString()); if (!packageJson.version || packageJson.version.startsWith('0.0.0')) { - newVersion = prerelease ? '0.0.1-canary.0' : '0.0.1'; + newVersion = prerelease ? "0.0.1-".concat(_context__WEBPACK_IMPORTED_MODULE_1__/* .prereleaseType */ .kD, ".0") : '0.0.1'; } else { - newVersion = prerelease ? semver_functions_inc__WEBPACK_IMPORTED_MODULE_0___default()(packageJson.version, 'prerelease', 'canary') : semver_functions_inc__WEBPACK_IMPORTED_MODULE_0___default()(packageJson.version, 'patch'); + newVersion = prerelease ? semver_functions_inc__WEBPACK_IMPORTED_MODULE_0___default()(packageJson.version, 'prerelease', _context__WEBPACK_IMPORTED_MODULE_1__/* .prereleaseType */ .kD) : semver_functions_inc__WEBPACK_IMPORTED_MODULE_0___default()(packageJson.version, 'patch'); } if (!newVersion) throw new Error('Could not increase version'); - packageJson.version = newVersion; return [ 4, _context__WEBPACK_IMPORTED_MODULE_1__/* .octo.rest.git.getRef */ .NR.rest.git.getRef({ owner: _context__WEBPACK_IMPORTED_MODULE_1__/* .owner */ .cR, repo: _context__WEBPACK_IMPORTED_MODULE_1__/* .repo */ .O9, - ref: "heads/main" + ref: "heads/".concat(_context__WEBPACK_IMPORTED_MODULE_1__/* .baseBranch */ .a2) }) ]; case 2: _ref1 = _state.sent(), _ref_data = _ref1.data, sha = _ref_data.object.sha; shortSha = sha.slice(0, 6) + sha.slice(-6); - branch = prerelease ? "turbo-module/release-".concat(shortSha, "-canary") : "turbo-module/release-".concat(shortSha); + branch = prerelease ? "turbo-module/release-".concat(shortSha, "-").concat(_context__WEBPACK_IMPORTED_MODULE_1__/* .prereleaseType */ .kD) : "turbo-module/release-".concat(shortSha); return [ 4, _context__WEBPACK_IMPORTED_MODULE_1__/* .octo.rest.git.createRef */ .NR.rest.git.createRef({ @@ -514,25 +517,92 @@ var createPull = function(prerelease) { ]; case 3: _state.sent(); + _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined; + _state.label = 4; + case 4: + _state.trys.push([ + 4, + 10, + 11, + 12 + ]); + _iterator = _context__WEBPACK_IMPORTED_MODULE_1__/* .versionFiles */ .dm[Symbol.iterator](); + _state.label = 5; + case 5: + if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [ + 3, + 9 + ]; + versionFile = _step.value; + filePath = (0,_context__WEBPACK_IMPORTED_MODULE_1__/* .withWorkingDir */ .QV)(versionFile); + console.log("Updating version in ".concat(filePath, " to ").concat(newVersion)); + return [ + 4, + _context__WEBPACK_IMPORTED_MODULE_1__/* .octo.rest.repos.getContent */ .NR.rest.repos.getContent({ + repo: _context__WEBPACK_IMPORTED_MODULE_1__/* .repo */ .O9, + owner: _context__WEBPACK_IMPORTED_MODULE_1__/* .owner */ .cR, + path: filePath, + ref: branch + }) + ]; + case 6: + _ref2 = _state.sent(), fileContent = _ref2.data; + if (!('content' in fileContent)) throw new Error("Could not get ".concat(filePath, " contents")); + filePackageJson = JSON.parse(Buffer.from(fileContent.content, 'base64').toString()); + filePackageJson.version = newVersion; return [ 4, _context__WEBPACK_IMPORTED_MODULE_1__/* .octo.rest.repos.createOrUpdateFileContents */ .NR.rest.repos.createOrUpdateFileContents({ repo: _context__WEBPACK_IMPORTED_MODULE_1__/* .repo */ .O9, owner: _context__WEBPACK_IMPORTED_MODULE_1__/* .owner */ .cR, - path: 'package.json', - message: "release patch ".concat(packageJson.version), - content: Buffer.from(JSON.stringify(packageJson, null, 2) + '\n').toString('base64'), - sha: content.sha, + path: filePath, + message: "release: ".concat(newVersion), + content: Buffer.from(JSON.stringify(filePackageJson, null, 2) + '\n').toString('base64'), + sha: fileContent.sha, branch: branch }) ]; - case 4: + case 7: _state.sent(); + _state.label = 8; + case 8: + _iteratorNormalCompletion = true; + return [ + 3, + 5 + ]; + case 9: + return [ + 3, + 12 + ]; + case 10: + err = _state.sent(); + _didIteratorError = true; + _iteratorError = err; + return [ + 3, + 12 + ]; + case 11: + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally{ + if (_didIteratorError) { + throw _iteratorError; + } + } + return [ + 7 + ]; + case 12: return [ 4, (0,_util_get_message__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(prerelease) ]; - case 5: + case 13: message = _state.sent().message; return [ 4, @@ -542,25 +612,25 @@ var createPull = function(prerelease) { title: title, body: message, head: branch, - base: 'main' + base: _context__WEBPACK_IMPORTED_MODULE_1__/* .baseBranch */ .a2 }) ]; - case 6: - _ref2 = _state.sent(), pull = _ref2.data; - err = 0; - _state.label = 7; - case 7: - if (!(err < 5)) return [ + case 14: + _ref3 = _state.sent(), pull = _ref3.data; + _$err = 0; + _state.label = 15; + case 15: + if (!(_$err < 5)) return [ 3, - 13 + 21 ]; - _state.label = 8; - case 8: + _state.label = 16; + case 16: _state.trys.push([ - 8, - 10, + 16, + 18, , - 12 + 20 ]); return [ 4, @@ -573,34 +643,34 @@ var createPull = function(prerelease) { ]) }) ]; - case 9: + case 17: _state.sent(); return [ 2, pull ]; - case 10: + case 18: e = _state.sent(); console.error(e); - err++; + _$err++; return [ 4, new Promise(function(resolve) { return setTimeout(resolve, 300); }) ]; - case 11: + case 19: _state.sent(); return [ 3, - 12 + 20 ]; - case 12: + case 20: return [ 3, - 7 + 15 ]; - case 13: + case 21: throw new Error('Could not add labels to PR'); } }); @@ -615,11 +685,17 @@ var createPull = function(prerelease) { /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "G": () => (/* binding */ canaryReleaseTitle), -/* harmony export */ "o": () => (/* binding */ fullReleaseTitle) +/* harmony export */ "e": () => (/* binding */ getPrereleaseTitle), +/* harmony export */ "n": () => (/* binding */ getFullReleaseTitle) /* harmony export */ }); -var fullReleaseTitle = '(turbo-module): release next version'; -var canaryReleaseTitle = '(turbo-module): release next canary version'; +/* harmony import */ var _context__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7501); + +var getFullReleaseTitle = function() { + return '(turbo-module): release next version'; +}; +var getPrereleaseTitle = function() { + return "(turbo-module): release next ".concat(_context__WEBPACK_IMPORTED_MODULE_0__/* .prereleaseType */ .kD, " version"); +}; /***/ }) diff --git a/packages/action/out/767.index.js b/packages/action/out/767.index.js index aadb4ff..bc10c35 100644 --- a/packages/action/out/767.index.js +++ b/packages/action/out/767.index.js @@ -10,12 +10,17 @@ exports.modules = { /* harmony export */ "NR": () => (/* binding */ octo), /* harmony export */ "O9": () => (/* binding */ repo), /* harmony export */ "PX": () => (/* binding */ target_issue), +/* harmony export */ "QV": () => (/* binding */ withWorkingDir), /* harmony export */ "RL": () => (/* binding */ target_comment), +/* harmony export */ "RP": () => (/* binding */ publishPackages), +/* harmony export */ "a2": () => (/* binding */ baseBranch), /* harmony export */ "cR": () => (/* binding */ owner), +/* harmony export */ "dm": () => (/* binding */ versionFiles), /* harmony export */ "hl": () => (/* binding */ commit_hash), +/* harmony export */ "kD": () => (/* binding */ prereleaseType), /* harmony export */ "sS": () => (/* binding */ initial_commit) /* harmony export */ }); -/* unused harmony export target_pull */ +/* unused harmony exports target_pull, workingDirectory */ /* harmony import */ var _actions_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1416); /* harmony import */ var _actions_core__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_actions_core__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _actions_github__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7036); @@ -29,6 +34,17 @@ var octo = (0,_actions_github__WEBPACK_IMPORTED_MODULE_1__.getOctokit)(GITHUB_TO var _context_repo = _actions_github__WEBPACK_IMPORTED_MODULE_1__.context.repo, _context_payload = _actions_github__WEBPACK_IMPORTED_MODULE_1__.context.payload; var owner = _context_repo.owner, repo = _context_repo.repo, commit_hash = _actions_github__WEBPACK_IMPORTED_MODULE_1__.context.sha, target_issue = _context_payload.issue, target_comment = _context_payload.comment, target_pull = _context_payload.pull_request; var initial_commit = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('initial-commit'); +// Monorepo support configuration +var workingDirectory = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('working-directory') || '.'; +var versionFiles = JSON.parse((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('version-files') || '["package.json"]'); +var publishPackages = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('publish-packages') ? JSON.parse((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('publish-packages')) : undefined; +var prereleaseType = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('prerelease-type') || 'canary'; +var baseBranch = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('base-branch') || 'main'; +// Helper to join working directory with a path +var withWorkingDir = function(path) { + if (workingDirectory === '.') return path; + return "".concat(workingDirectory, "/").concat(path); +}; /***/ }), diff --git a/packages/action/out/967.index.js b/packages/action/out/967.index.js index 4921f90..6d06d71 100644 --- a/packages/action/out/967.index.js +++ b/packages/action/out/967.index.js @@ -390,12 +390,20 @@ var release = function() { /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); -var isCanary = function(test) { - return /^\d+\.\d+\.\d+-canary\.\d+$/.test(test); +/* unused harmony export isPrerelease */ +/* harmony import */ var _context__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7501); + +// Check if version matches the configured prerelease type (e.g., canary, beta) +var isPrerelease = function(test) { + var pattern = new RegExp("^\\d+\\.\\d+\\.\\d+-".concat(_context__WEBPACK_IMPORTED_MODULE_0__/* .prereleaseType */ .kD, "\\.\\d+$")); + return pattern.test(test); }; +// Legacy export for backwards compatibility +var isCanary = isPrerelease; /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isCanary); + /***/ }) }; diff --git a/packages/action/src/check/index.ts b/packages/action/src/check/index.ts index df38ca8..3f4d672 100644 --- a/packages/action/src/check/index.ts +++ b/packages/action/src/check/index.ts @@ -3,9 +3,18 @@ import { bash, command } from '../util/exec'; import isCanary from '../util/is-canary'; import { gt } from 'semver'; import { getFolder, getJsonFile, JSONFile } from '../util/get-file'; +import { + publishPackages, + prereleaseType, + versionFiles, + withWorkingDir, +} from '../context'; -const versionParserRegexp = - /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*@(\d+\.\d+\.\d+(?:-canary\.\d+)?)/; +// Dynamic regex that supports the configured prerelease type +const createVersionParserRegexp = () => + new RegExp( + `^(@[a-z0-9-~][a-z0-9-._~]*/)?[a-z0-9-~][a-z0-9-._~]*@(\\d+\\.\\d+\\.\\d+(?:-${prereleaseType}\\.\\d+)?)`, + ); const checkPackage = async (pkg: JSONFile, rootVersion: string) => { try { @@ -23,11 +32,12 @@ const checkPackage = async (pkg: JSONFile, rootVersion: string) => { try { const [res] = await bash` ${command` - npm view - ${packageJson.name}@${isCanary(rootVersion) ? 'canary' : 'latest'} + npm view + ${packageJson.name}@${isCanary(rootVersion) ? prereleaseType : 'latest'} `} `; if (!res) throw new Error('Ăšnexpected error'); + const versionParserRegexp = createVersionParserRegexp(); const [, , currentVersion] = versionParserRegexp.exec(res.stdout.trim()) || []; if (!currentVersion) @@ -50,12 +60,31 @@ const checkPackage = async (pkg: JSONFile, rootVersion: string) => { }; const checkPackages = async (rootVersion: string) => { - const folders = await getFolder('packages'); + // If publish-packages is configured, use those specific paths + if (publishPackages && publishPackages.length > 0) { + console.log('checking configured packages: ' + publishPackages.join(', ')); + return ( + await Promise.all( + publishPackages.map(async (pkgPath) => { + const fullPath = withWorkingDir(pkgPath); + // If path doesn't end with package.json, append it + const jsonPath = fullPath.endsWith('package.json') + ? fullPath + : `${fullPath}/package.json`; + return checkPackage(jsonPath as JSONFile, rootVersion); + }), + ) + ).filter(Boolean) as string[]; + } + + // Otherwise, scan packages/* directory (legacy behavior) + const packagesDir = withWorkingDir('packages'); + const folders = await getFolder(packagesDir); console.log('checking ' + folders.map(({ path }) => path).join()); return ( await Promise.all( folders.map(async ({ path }) => - checkPackage(`${path}/package.json`, rootVersion), + checkPackage(`${path}/package.json` as JSONFile, rootVersion), ), ) ).filter(Boolean) as string[]; @@ -69,10 +98,17 @@ const checkPackages = async (rootVersion: string) => { * inteded to be ran as part of a workflow */ const canPublish = async () => { + // Use the first version file as the source of truth for the version + const versionFilePath = withWorkingDir(versionFiles[0]); const { content: { version }, - } = await getJsonFile<{ version: string }>('package.json'); - console.log('version:', version, 'is canary:', isCanary(version)); + } = await getJsonFile<{ version: string }>(versionFilePath as JSONFile); + console.log( + 'version:', + version, + `is ${prereleaseType}:`, + isCanary(version), + ); // any version starting with 0.0.0 is considered a initial dev // version and will not be published if (version.startsWith('0.0.0')) { diff --git a/packages/action/src/context.ts b/packages/action/src/context.ts index 0effb9f..06299b3 100644 --- a/packages/action/src/context.ts +++ b/packages/action/src/context.ts @@ -16,3 +16,20 @@ export const { } = context; export const initial_commit: string | undefined = getInput('initial-commit'); + +// Monorepo support configuration +export const workingDirectory: string = getInput('working-directory') || '.'; +export const versionFiles: string[] = JSON.parse( + getInput('version-files') || '["package.json"]', +); +export const publishPackages: string[] | undefined = getInput('publish-packages') + ? JSON.parse(getInput('publish-packages')) + : undefined; +export const prereleaseType: string = getInput('prerelease-type') || 'canary'; +export const baseBranch: string = getInput('base-branch') || 'main'; + +// Helper to join working directory with a path +export const withWorkingDir = (path: string): string => { + if (workingDirectory === '.') return path; + return `${workingDirectory}/${path}`; +}; diff --git a/packages/action/src/release-pull/create.ts b/packages/action/src/release-pull/create.ts index ffe2fdd..1542745 100644 --- a/packages/action/src/release-pull/create.ts +++ b/packages/action/src/release-pull/create.ts @@ -1,13 +1,24 @@ import inc from 'semver/functions/inc'; -import { octo, owner, repo } from '../context'; +import { + octo, + owner, + repo, + versionFiles, + prereleaseType, + baseBranch, + withWorkingDir, +} from '../context'; import getReleaseMessage from '../util/get-message'; import isActionUser from '../util/is-action-user'; import { Pull } from '../util/types'; -import { canaryReleaseTitle, fullReleaseTitle } from './shared'; +import { getPrereleaseTitle, getFullReleaseTitle } from './shared'; const runAction = async () => { + const fullReleaseTitle = getFullReleaseTitle(); + const prereleaseTitle = getPrereleaseTitle(); + const stale: Pull[] = []; - const staleCanary: Pull[] = []; + const stalePrerelease: Pull[] = []; for await (const { data: pulls } of octo.paginate.iterator( octo.rest.pulls.list, { @@ -22,12 +33,12 @@ const runAction = async () => { for (const pull of pulls) { if (isActionUser(pull.user)) { if (fullReleaseTitle === pull.title) stale.push(pull); - else if (canaryReleaseTitle === pull.title) staleCanary.push(pull); + else if (prereleaseTitle === pull.title) stalePrerelease.push(pull); } } // close stale PRs and delete the branches await Promise.all( - [...stale, ...staleCanary].map(async (stalePull) => { + [...stale, ...stalePrerelease].map(async (stalePull) => { await octo.rest.pulls.update({ repo, owner, @@ -42,15 +53,15 @@ const runAction = async () => { }), ); - const [canaryPull, fullPull] = await Promise.all([ + const [prereleasePull, fullPull] = await Promise.all([ createPull(true), createPull(false), ]); // add comments to closed PRs that link to the newly created PRs await Promise.all([ Promise.all( - staleCanary.map((pull) => - addCommentToClosed(pull.number, canaryPull.number), + stalePrerelease.map((pull) => + addCommentToClosed(pull.number, prereleasePull.number), ), ), Promise.all( @@ -71,28 +82,34 @@ const addCommentToClosed = async (number: number, replacement: number) => { const pull_labels = ['auto-release-pr', 'keep up-to-date']; export const createPull = async (prerelease: boolean) => { - const title = prerelease ? canaryReleaseTitle : fullReleaseTitle; - const releaseLabel = prerelease ? 'releases: canary' : 'releases: patch'; + const title = prerelease ? getPrereleaseTitle() : getFullReleaseTitle(); + const releaseLabel = prerelease + ? `releases: ${prereleaseType}` + : 'releases: patch'; + + // Get the first version file to determine current version + const primaryVersionFile = withWorkingDir(versionFiles[0]); const { data: content } = await octo.rest.repos.getContent({ repo, owner, - path: 'package.json', + path: primaryVersionFile, }); if (!('content' in content)) throw new Error('Could not get package.json contents'); const packageJson = JSON.parse( Buffer.from(content.content, 'base64').toString(), ) as { version?: string }; + let newVersion: string | null; if (!packageJson.version || packageJson.version.startsWith('0.0.0')) { - newVersion = prerelease ? '0.0.1-canary.0' : '0.0.1'; + newVersion = prerelease ? `0.0.1-${prereleaseType}.0` : '0.0.1'; } else { newVersion = prerelease - ? inc(packageJson.version, 'prerelease', 'canary') + ? inc(packageJson.version, 'prerelease', prereleaseType) : inc(packageJson.version, 'patch'); } if (!newVersion) throw new Error('Could not increase version'); - packageJson.version = newVersion; + const { data: { object: { sha }, @@ -100,29 +117,52 @@ export const createPull = async (prerelease: boolean) => { } = await octo.rest.git.getRef({ owner, repo, - ref: `heads/main`, + ref: `heads/${baseBranch}`, }); const shortSha = sha.slice(0, 6) + sha.slice(-6); const branch = prerelease - ? `turbo-module/release-${shortSha}-canary` + ? `turbo-module/release-${shortSha}-${prereleaseType}` : `turbo-module/release-${shortSha}`; + await octo.rest.git.createRef({ owner, repo, sha, ref: `refs/heads/${branch}`, }); - await octo.rest.repos.createOrUpdateFileContents({ - repo, - owner, - path: 'package.json', - message: `release patch ${packageJson.version}`, - content: Buffer.from(JSON.stringify(packageJson, null, 2) + '\n').toString( - 'base64', - ), - sha: content.sha, - branch, - }); + + // Update all version files with the new version + for (const versionFile of versionFiles) { + const filePath = withWorkingDir(versionFile); + console.log(`Updating version in ${filePath} to ${newVersion}`); + + const { data: fileContent } = await octo.rest.repos.getContent({ + repo, + owner, + path: filePath, + ref: branch, + }); + if (!('content' in fileContent)) + throw new Error(`Could not get ${filePath} contents`); + + const filePackageJson = JSON.parse( + Buffer.from(fileContent.content, 'base64').toString(), + ) as { version?: string }; + filePackageJson.version = newVersion; + + await octo.rest.repos.createOrUpdateFileContents({ + repo, + owner, + path: filePath, + message: `release: ${newVersion}`, + content: Buffer.from( + JSON.stringify(filePackageJson, null, 2) + '\n', + ).toString('base64'), + sha: fileContent.sha, + branch, + }); + } + const { message } = await getReleaseMessage(prerelease); const { data: pull } = await octo.rest.pulls.create({ repo, @@ -130,7 +170,7 @@ export const createPull = async (prerelease: boolean) => { title, body: message, head: branch, - base: 'main', + base: baseBranch, }); let err = 0; while (err < 5) { diff --git a/packages/action/src/release-pull/shared.ts b/packages/action/src/release-pull/shared.ts index d0f0ff2..27196c4 100644 --- a/packages/action/src/release-pull/shared.ts +++ b/packages/action/src/release-pull/shared.ts @@ -1,2 +1,5 @@ -export const fullReleaseTitle = '(turbo-module): release next version'; -export const canaryReleaseTitle = '(turbo-module): release next canary version'; +import { prereleaseType } from '../context'; + +export const getFullReleaseTitle = () => '(turbo-module): release next version'; +export const getPrereleaseTitle = () => + `(turbo-module): release next ${prereleaseType} version`; diff --git a/packages/action/src/release-pull/sync.ts b/packages/action/src/release-pull/sync.ts index 71f75e0..1347f53 100644 --- a/packages/action/src/release-pull/sync.ts +++ b/packages/action/src/release-pull/sync.ts @@ -2,7 +2,7 @@ import isActionUser from '../util/is-action-user'; import { octo, owner, repo } from '../context'; import getReleaseMessage from '../util/get-message'; import { Pull } from '../util/types'; -import { canaryReleaseTitle, fullReleaseTitle } from './shared'; +import { getFullReleaseTitle, getPrereleaseTitle } from './shared'; import { createPull } from './create'; const syncPull = async (pull: Pull, prerelease: boolean) => { @@ -19,8 +19,11 @@ const syncPull = async (pull: Pull, prerelease: boolean) => { }; const runAction = async () => { + const fullReleaseTitle = getFullReleaseTitle(); + const prereleaseTitle = getPrereleaseTitle(); + let full: Promise | undefined; - let canary: Promise | undefined; + let prerelease: Promise | undefined; for await (const { data: pulls } of octo.paginate.iterator( octo.rest.pulls.list, { @@ -39,21 +42,21 @@ const runAction = async () => { if (!full) full = syncPull(pull, false); break; } - case canaryReleaseTitle: { - if (!canary) canary = syncPull(pull, true); + case prereleaseTitle: { + if (!prerelease) prerelease = syncPull(pull, true); break; } } } - if (full && canary) break; + if (full && prerelease) break; } - if (full && canary) break; + if (full && prerelease) break; } if (!full) full = createPull(false); - if (!canary) canary = createPull(true); + if (!prerelease) prerelease = createPull(true); - await Promise.all([full, canary]); + await Promise.all([full, prerelease]); }; export default runAction; diff --git a/packages/action/src/release-pull/type.ts b/packages/action/src/release-pull/type.ts index fcc6c39..85e2ff4 100644 --- a/packages/action/src/release-pull/type.ts +++ b/packages/action/src/release-pull/type.ts @@ -1,16 +1,26 @@ import { inc } from 'semver'; -import { octo, owner, repo, target_comment, target_issue } from '../context'; +import { + octo, + owner, + repo, + target_comment, + target_issue, + versionFiles, + prereleaseType, + baseBranch, + withWorkingDir, +} from '../context'; import getCodeOwners from '../util/get-codeowners'; const types = ['patch', 'minor', 'major'] as const; type ReleaseTypes = (typeof types)[number]; -const getPackageJson = async (ref?: string) => { +const getPackageJson = async (path: string, ref?: string) => { const { data: content } = await octo.rest.repos.getContent({ repo, owner, - path: 'package.json', + path, ref, }); if ('content' in content) { @@ -23,7 +33,7 @@ const getPackageJson = async (ref?: string) => { sha: content.sha, }; } - throw new Error('Could not load main package.json'); + throw new Error(`Could not load ${path}`); }; const performUpdate = async (type: ReleaseTypes) => { @@ -39,19 +49,18 @@ const performUpdate = async (type: ReleaseTypes) => { owner, pull_number: target_issue.number, }); - /* await octo.rest.pulls.updateBranch({ - repo, - owner, - pull_number: target_issue.number, - }); */ + const releaseTypeLabel = labels.find(({ name }) => name.startsWith('releases: '), ); const current_type = releaseTypeLabel?.name.replace('releases: ', ''); - if (current_type === 'canary' || type === current_type) return; - const { content: mainPackageJson } = await getPackageJson('main'); - const { content: currentPackageJson, sha: packageSha } = await getPackageJson( - branch, + // Skip if it's a prerelease PR or already the requested type + if (current_type === prereleaseType || type === current_type) return; + + const primaryVersionFile = withWorkingDir(versionFiles[0]); + const { content: mainPackageJson } = await getPackageJson( + primaryVersionFile, + baseBranch, ); const currentVersion = mainPackageJson.version.startsWith('0.0.0') ? '0.0.0' @@ -60,20 +69,27 @@ const performUpdate = async (type: ReleaseTypes) => { if (!newVersion) throw new Error(`Could not increase ${type} for ${currentVersion}`); - if (currentPackageJson.version !== newVersion) { - currentPackageJson.version = newVersion; + // Update all version files + for (const versionFile of versionFiles) { + const filePath = withWorkingDir(versionFile); + const { content: currentPackageJson, sha: packageSha } = + await getPackageJson(filePath, branch); - await octo.rest.repos.createOrUpdateFileContents({ - repo, - owner, - path: 'package.json', - message: `release ${type} ${newVersion}`, - content: Buffer.from( - JSON.stringify(currentPackageJson, null, 2) + '\n', - ).toString('base64'), - sha: packageSha, - branch, - }); + if (currentPackageJson.version !== newVersion) { + currentPackageJson.version = newVersion; + + await octo.rest.repos.createOrUpdateFileContents({ + repo, + owner, + path: filePath, + message: `release ${type} ${newVersion}`, + content: Buffer.from( + JSON.stringify(currentPackageJson, null, 2) + '\n', + ).toString('base64'), + sha: packageSha, + branch, + }); + } } const promises: Promise[] = [ diff --git a/packages/action/src/util/is-canary.ts b/packages/action/src/util/is-canary.ts index bfdf7c0..91fbdcb 100644 --- a/packages/action/src/util/is-canary.ts +++ b/packages/action/src/util/is-canary.ts @@ -1,3 +1,13 @@ -const isCanary = (test: string) => /^\d+\.\d+\.\d+-canary\.\d+$/.test(test); +import { prereleaseType } from '../context'; + +// Check if version matches the configured prerelease type (e.g., canary, beta) +const isPrerelease = (test: string) => { + const pattern = new RegExp(`^\\d+\\.\\d+\\.\\d+-${prereleaseType}\\.\\d+$`); + return pattern.test(test); +}; + +// Legacy export for backwards compatibility +const isCanary = isPrerelease; export default isCanary; +export { isPrerelease }; From b22b3bad16dbdc640d2208893a47f518171eebdc Mon Sep 17 00:00:00 2001 From: Jack Sharkey Date: Sat, 27 Dec 2025 19:00:44 +0900 Subject: [PATCH 2/8] fix: handle non-existent PRs in changelog generation --- packages/action/out/767.index.js | 94 +++++++++++++-------- packages/action/src/util/collect-commits.ts | 30 ++++--- 2 files changed, 75 insertions(+), 49 deletions(-) diff --git a/packages/action/out/767.index.js b/packages/action/out/767.index.js index bc10c35..2ffcff9 100644 --- a/packages/action/out/767.index.js +++ b/packages/action/out/767.index.js @@ -245,7 +245,7 @@ var addPull = function(pulls, type, number, title) { }; var collectCommits = function(head, base) { return _async_to_generator(function() { - var stats, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, commits, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, commit, _exec, _commit_author, message, PR, pull_number, _ref, pr, areas, _iteratorNormalCompletion1, _didIteratorError2, _iteratorError2, _iterator2, _step2, area, err, err1; + var stats, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, commits, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, commit, _exec, _commit_author, message, PR, pull_number, _ref, pr, areas, _iteratorNormalCompletion1, _didIteratorError2, _iteratorError2, _iterator2, _step2, area, e, err, err1; return _ts_generator(this, function(_state) { switch(_state.label){ case 0: @@ -258,9 +258,9 @@ var collectCommits = function(head, base) { case 1: _state.trys.push([ 1, - 13, - 14, - 19 + 15, + 16, + 21 ]); _iterator = _async_iterator(context/* octo.paginate.iterator */.NR.paginate.iterator(context/* octo.rest.repos.compareCommits */.NR.rest.repos.compareCommits, { owner: context/* owner */.cR, @@ -278,7 +278,7 @@ var collectCommits = function(head, base) { case 3: if (!(_iteratorAbruptCompletion = !(_step = _state.sent()).done)) return [ 3, - 12 + 14 ]; _value = _step.value; commits = _value.data.commits; @@ -287,36 +287,44 @@ var collectCommits = function(head, base) { case 4: _state.trys.push([ 4, - 9, - 10, - 11 + 11, + 12, + 13 ]); _iterator1 = commits[Symbol.iterator](); _state.label = 5; case 5: if (!!(_iteratorNormalCompletion = (_step1 = _iterator1.next()).done)) return [ 3, - 8 + 10 ]; commit = _step1.value; message = commit.commit.message.split('\n')[0]; PR = (_exec = /\(#(\d+)\)$/.exec(message)) === null || _exec === void 0 ? void 0 : _exec[1]; if (!PR) return [ 3, - 7 + 9 ]; pull_number = parseInt(PR); if ((_commit_author = commit.author) === null || _commit_author === void 0 ? void 0 : _commit_author.login) { if ((0,is_action_user/* default */.Z)(commit.author) && message.startsWith('release ')) return [ 3, - 7 + 9 ]; if (message.startsWith('(turbo-module): ')) return [ 3, - 7 + 9 ]; stats.authors.add(commit.author.login); } + _state.label = 6; + case 6: + _state.trys.push([ + 6, + 8, + , + 9 + ]); return [ 4, context/* octo.rest.pulls.get */.NR.rest.pulls.get({ @@ -325,7 +333,7 @@ var collectCommits = function(head, base) { pull_number: pull_number }) ]; - case 6: + case 7: _ref = _state.sent(), pr = _ref.data; areas = pr.labels.filter(function(param) { var name = param.name; @@ -356,27 +364,39 @@ var collectCommits = function(head, base) { } } } - _state.label = 7; - case 7: - _iteratorNormalCompletion = true; return [ 3, - 5 + 9 ]; case 8: + e = _state.sent(); + // PR might not exist in this repo (e.g., monorepo with commits from other repos) + console.log("Skipping PR #".concat(pull_number, " - not found in this repo")); + addPull(stats.pulls, 'general', pull_number, message); return [ 3, - 11 + 9 ]; case 9: + _iteratorNormalCompletion = true; + return [ + 3, + 5 + ]; + case 10: + return [ + 3, + 13 + ]; + case 11: err = _state.sent(); _didIteratorError1 = true; _iteratorError1 = err; return [ 3, - 11 + 13 ]; - case 10: + case 12: try { if (!_iteratorNormalCompletion && _iterator1.return != null) { _iterator1.return(); @@ -389,60 +409,60 @@ var collectCommits = function(head, base) { return [ 7 ]; - case 11: + case 13: _iteratorAbruptCompletion = false; return [ 3, 2 ]; - case 12: + case 14: return [ 3, - 19 + 21 ]; - case 13: + case 15: err1 = _state.sent(); _didIteratorError = true; _iteratorError = err1; return [ 3, - 19 + 21 ]; - case 14: + case 16: _state.trys.push([ - 14, + 16, , - 17, - 18 + 19, + 20 ]); if (!(_iteratorAbruptCompletion && _iterator.return != null)) return [ 3, - 16 + 18 ]; return [ 4, _iterator.return() ]; - case 15: + case 17: _state.sent(); - _state.label = 16; - case 16: + _state.label = 18; + case 18: return [ 3, - 18 + 20 ]; - case 17: + case 19: if (_didIteratorError) { throw _iteratorError; } return [ 7 ]; - case 18: + case 20: return [ 7 ]; - case 19: + case 21: return [ 2, stats diff --git a/packages/action/src/util/collect-commits.ts b/packages/action/src/util/collect-commits.ts index a0ddd59..bb5475e 100644 --- a/packages/action/src/util/collect-commits.ts +++ b/packages/action/src/util/collect-commits.ts @@ -37,20 +37,26 @@ const collectCommits = async (head: string, base: string) => { if (message.startsWith('(turbo-module): ')) continue; stats.authors.add(commit.author.login); } - const { data: pr } = await octo.rest.pulls.get({ - repo, - owner, - pull_number, - }); - const areas = pr.labels - .filter(({ name }) => /^area: /.test(name)) - .map(({ name }) => name.replace(/^area: /, '')); + try { + const { data: pr } = await octo.rest.pulls.get({ + repo, + owner, + pull_number, + }); + const areas = pr.labels + .filter(({ name }) => /^area: /.test(name)) + .map(({ name }) => name.replace(/^area: /, '')); - if (!areas.length) { + if (!areas.length) { + addPull(stats.pulls, 'general', pull_number, message); + } else + for (const area of areas) + addPull(stats.pulls, area, pull_number, message); + } catch (e) { + // PR might not exist in this repo (e.g., monorepo with commits from other repos) + console.log(`Skipping PR #${pull_number} - not found in this repo`); addPull(stats.pulls, 'general', pull_number, message); - } else - for (const area of areas) - addPull(stats.pulls, area, pull_number, message); + } } return stats; }; From dad7c456dd3c7454f445170b4ae8a2d694acf0bb Mon Sep 17 00:00:00 2001 From: Jack Sharkey Date: Sat, 27 Dec 2025 19:22:29 +0900 Subject: [PATCH 3/8] feat: add configurable max-changelog-commits limit --- action.yml | 3 +++ packages/action/out/212.index.js | 2 ++ packages/action/out/587.index.js | 2 ++ packages/action/out/767.index.js | 13 ++++++++++++- packages/action/src/context.ts | 1 + packages/action/src/util/collect-commits.ts | 11 +++++++++-- 6 files changed, 29 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index ab350c1..2d9b733 100644 --- a/action.yml +++ b/action.yml @@ -31,3 +31,6 @@ inputs: base-branch: description: "Base branch for PRs and releases" default: "main" + max-changelog-commits: + description: "Maximum commits to scan for changelog generation (0 = unlimited)" + default: "100" diff --git a/packages/action/out/212.index.js b/packages/action/out/212.index.js index c1611f7..bb8cf6c 100644 --- a/packages/action/out/212.index.js +++ b/packages/action/out/212.index.js @@ -1017,6 +1017,7 @@ var checkPackages = function(rootVersion) { /* harmony export */ "dm": () => (/* binding */ versionFiles), /* harmony export */ "hl": () => (/* binding */ commit_hash), /* harmony export */ "kD": () => (/* binding */ prereleaseType), +/* harmony export */ "pE": () => (/* binding */ maxChangelogCommits), /* harmony export */ "sS": () => (/* binding */ initial_commit) /* harmony export */ }); /* unused harmony exports target_pull, workingDirectory */ @@ -1039,6 +1040,7 @@ var versionFiles = JSON.parse((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getI var publishPackages = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('publish-packages') ? JSON.parse((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('publish-packages')) : undefined; var prereleaseType = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('prerelease-type') || 'canary'; var baseBranch = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('base-branch') || 'main'; +var maxChangelogCommits = parseInt((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('max-changelog-commits') || '100', 10); // Helper to join working directory with a path var withWorkingDir = function(path) { if (workingDirectory === '.') return path; diff --git a/packages/action/out/587.index.js b/packages/action/out/587.index.js index 23aa697..7bb6fc0 100644 --- a/packages/action/out/587.index.js +++ b/packages/action/out/587.index.js @@ -18,6 +18,7 @@ exports.modules = { /* harmony export */ "dm": () => (/* binding */ versionFiles), /* harmony export */ "hl": () => (/* binding */ commit_hash), /* harmony export */ "kD": () => (/* binding */ prereleaseType), +/* harmony export */ "pE": () => (/* binding */ maxChangelogCommits), /* harmony export */ "sS": () => (/* binding */ initial_commit) /* harmony export */ }); /* unused harmony exports target_pull, workingDirectory */ @@ -40,6 +41,7 @@ var versionFiles = JSON.parse((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getI var publishPackages = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('publish-packages') ? JSON.parse((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('publish-packages')) : undefined; var prereleaseType = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('prerelease-type') || 'canary'; var baseBranch = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('base-branch') || 'main'; +var maxChangelogCommits = parseInt((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('max-changelog-commits') || '100', 10); // Helper to join working directory with a path var withWorkingDir = function(path) { if (workingDirectory === '.') return path; diff --git a/packages/action/out/767.index.js b/packages/action/out/767.index.js index 2ffcff9..dfdbb7e 100644 --- a/packages/action/out/767.index.js +++ b/packages/action/out/767.index.js @@ -18,6 +18,7 @@ exports.modules = { /* harmony export */ "dm": () => (/* binding */ versionFiles), /* harmony export */ "hl": () => (/* binding */ commit_hash), /* harmony export */ "kD": () => (/* binding */ prereleaseType), +/* harmony export */ "pE": () => (/* binding */ maxChangelogCommits), /* harmony export */ "sS": () => (/* binding */ initial_commit) /* harmony export */ }); /* unused harmony exports target_pull, workingDirectory */ @@ -40,6 +41,7 @@ var versionFiles = JSON.parse((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getI var publishPackages = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('publish-packages') ? JSON.parse((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('publish-packages')) : undefined; var prereleaseType = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('prerelease-type') || 'canary'; var baseBranch = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('base-branch') || 'main'; +var maxChangelogCommits = parseInt((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('max-changelog-commits') || '100', 10); // Helper to join working directory with a path var withWorkingDir = function(path) { if (workingDirectory === '.') return path; @@ -245,7 +247,7 @@ var addPull = function(pulls, type, number, title) { }; var collectCommits = function(head, base) { return _async_to_generator(function() { - var stats, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, commits, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, commit, _exec, _commit_author, message, PR, pull_number, _ref, pr, areas, _iteratorNormalCompletion1, _didIteratorError2, _iteratorError2, _iterator2, _step2, area, e, err, err1; + var stats, commitCount, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, commits, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, commit, _exec, _commit_author, message, PR, pull_number, _ref, pr, areas, _iteratorNormalCompletion1, _didIteratorError2, _iteratorError2, _iterator2, _step2, area, e, err, err1; return _ts_generator(this, function(_state) { switch(_state.label){ case 0: @@ -253,6 +255,7 @@ var collectCommits = function(head, base) { authors: new Set(), pulls: {} }; + commitCount = 0; _iteratorAbruptCompletion = false, _didIteratorError = false; _state.label = 1; case 1: @@ -299,6 +302,14 @@ var collectCommits = function(head, base) { 10 ]; commit = _step1.value; + if (context/* maxChangelogCommits */.pE > 0 && commitCount >= context/* maxChangelogCommits */.pE) { + console.log("Reached max commit limit (".concat(context/* maxChangelogCommits */.pE, "), stopping changelog scan")); + return [ + 2, + stats + ]; + } + commitCount++; message = commit.commit.message.split('\n')[0]; PR = (_exec = /\(#(\d+)\)$/.exec(message)) === null || _exec === void 0 ? void 0 : _exec[1]; if (!PR) return [ diff --git a/packages/action/src/context.ts b/packages/action/src/context.ts index 06299b3..30b28b0 100644 --- a/packages/action/src/context.ts +++ b/packages/action/src/context.ts @@ -27,6 +27,7 @@ export const publishPackages: string[] | undefined = getInput('publish-packages' : undefined; export const prereleaseType: string = getInput('prerelease-type') || 'canary'; export const baseBranch: string = getInput('base-branch') || 'main'; +export const maxChangelogCommits: number = parseInt(getInput('max-changelog-commits') || '100', 10); // Helper to join working directory with a path export const withWorkingDir = (path: string): string => { diff --git a/packages/action/src/util/collect-commits.ts b/packages/action/src/util/collect-commits.ts index bb5475e..c8f0c4e 100644 --- a/packages/action/src/util/collect-commits.ts +++ b/packages/action/src/util/collect-commits.ts @@ -1,4 +1,4 @@ -import { octo, owner, repo } from '../context'; +import { octo, owner, repo, maxChangelogCommits } from '../context'; import isActionUser from './is-action-user'; import { ReleasePulls, ReleaseStats } from './types'; @@ -17,6 +17,7 @@ const collectCommits = async (head: string, base: string) => { authors: new Set(), pulls: {}, }; + let commitCount = 0; for await (const { data: { commits }, } of octo.paginate.iterator(octo.rest.repos.compareCommits, { @@ -25,8 +26,13 @@ const collectCommits = async (head: string, base: string) => { base, head, per_page: 100, - })) + })) { for (const commit of commits) { + if (maxChangelogCommits > 0 && commitCount >= maxChangelogCommits) { + console.log(`Reached max commit limit (${maxChangelogCommits}), stopping changelog scan`); + return stats; + } + commitCount++; const message = commit.commit.message.split('\n')[0]; const PR = /\(#(\d+)\)$/.exec(message)?.[1]; if (!PR) continue; @@ -58,6 +64,7 @@ const collectCommits = async (head: string, base: string) => { addPull(stats.pulls, 'general', pull_number, message); } } + } return stats; }; From 1ddff5277654cf45cdc97e5ded5614f031d8a6cf Mon Sep 17 00:00:00 2001 From: Jack Sharkey Date: Sat, 27 Dec 2025 19:31:09 +0900 Subject: [PATCH 4/8] fix: filter changelog by working directory Only include commits that touch files in the working directory to prevent monorepo changelogs from including unrelated commits. --- packages/action/out/212.index.js | 3 +- packages/action/out/587.index.js | 3 +- packages/action/out/767.index.js | 148 ++++++++++++++------ packages/action/src/util/collect-commits.ts | 30 +++- 4 files changed, 139 insertions(+), 45 deletions(-) diff --git a/packages/action/out/212.index.js b/packages/action/out/212.index.js index bb8cf6c..c9377d9 100644 --- a/packages/action/out/212.index.js +++ b/packages/action/out/212.index.js @@ -1012,6 +1012,7 @@ var checkPackages = function(rootVersion) { /* harmony export */ "QV": () => (/* binding */ withWorkingDir), /* harmony export */ "RL": () => (/* binding */ target_comment), /* harmony export */ "RP": () => (/* binding */ publishPackages), +/* harmony export */ "Tf": () => (/* binding */ workingDirectory), /* harmony export */ "a2": () => (/* binding */ baseBranch), /* harmony export */ "cR": () => (/* binding */ owner), /* harmony export */ "dm": () => (/* binding */ versionFiles), @@ -1020,7 +1021,7 @@ var checkPackages = function(rootVersion) { /* harmony export */ "pE": () => (/* binding */ maxChangelogCommits), /* harmony export */ "sS": () => (/* binding */ initial_commit) /* harmony export */ }); -/* unused harmony exports target_pull, workingDirectory */ +/* unused harmony export target_pull */ /* harmony import */ var _actions_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1416); /* harmony import */ var _actions_core__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_actions_core__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _actions_github__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7036); diff --git a/packages/action/out/587.index.js b/packages/action/out/587.index.js index 7bb6fc0..a2da5d6 100644 --- a/packages/action/out/587.index.js +++ b/packages/action/out/587.index.js @@ -13,6 +13,7 @@ exports.modules = { /* harmony export */ "QV": () => (/* binding */ withWorkingDir), /* harmony export */ "RL": () => (/* binding */ target_comment), /* harmony export */ "RP": () => (/* binding */ publishPackages), +/* harmony export */ "Tf": () => (/* binding */ workingDirectory), /* harmony export */ "a2": () => (/* binding */ baseBranch), /* harmony export */ "cR": () => (/* binding */ owner), /* harmony export */ "dm": () => (/* binding */ versionFiles), @@ -21,7 +22,7 @@ exports.modules = { /* harmony export */ "pE": () => (/* binding */ maxChangelogCommits), /* harmony export */ "sS": () => (/* binding */ initial_commit) /* harmony export */ }); -/* unused harmony exports target_pull, workingDirectory */ +/* unused harmony export target_pull */ /* harmony import */ var _actions_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1416); /* harmony import */ var _actions_core__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_actions_core__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _actions_github__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7036); diff --git a/packages/action/out/767.index.js b/packages/action/out/767.index.js index dfdbb7e..df95547 100644 --- a/packages/action/out/767.index.js +++ b/packages/action/out/767.index.js @@ -13,6 +13,7 @@ exports.modules = { /* harmony export */ "QV": () => (/* binding */ withWorkingDir), /* harmony export */ "RL": () => (/* binding */ target_comment), /* harmony export */ "RP": () => (/* binding */ publishPackages), +/* harmony export */ "Tf": () => (/* binding */ workingDirectory), /* harmony export */ "a2": () => (/* binding */ baseBranch), /* harmony export */ "cR": () => (/* binding */ owner), /* harmony export */ "dm": () => (/* binding */ versionFiles), @@ -21,7 +22,7 @@ exports.modules = { /* harmony export */ "pE": () => (/* binding */ maxChangelogCommits), /* harmony export */ "sS": () => (/* binding */ initial_commit) /* harmony export */ }); -/* unused harmony exports target_pull, workingDirectory */ +/* unused harmony export target_pull */ /* harmony import */ var _actions_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1416); /* harmony import */ var _actions_core__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_actions_core__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _actions_github__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7036); @@ -245,6 +246,57 @@ var addPull = function(pulls, type, number, title) { title: title }); }; +// Check if a commit touches files in the working directory +var commitTouchesWorkingDir = function(sha) { + return _async_to_generator(function() { + var _commit_files, _ref, commit, _ref1, touchesDir, e; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + if (context/* workingDirectory */.Tf === '.') return [ + 2, + true + ]; // No filtering needed for root + _state.label = 1; + case 1: + _state.trys.push([ + 1, + 3, + , + 4 + ]); + return [ + 4, + context/* octo.rest.repos.getCommit */.NR.rest.repos.getCommit({ + owner: context/* owner */.cR, + repo: context/* repo */.O9, + ref: sha + }) + ]; + case 2: + _ref = _state.sent(), commit = _ref.data; + touchesDir = (_ref1 = (_commit_files = commit.files) === null || _commit_files === void 0 ? void 0 : _commit_files.some(function(file) { + return file.filename.startsWith("".concat(context/* workingDirectory */.Tf, "/")); + })) !== null && _ref1 !== void 0 ? _ref1 : false; + return [ + 2, + touchesDir + ]; + case 3: + e = _state.sent(); + // If we can't fetch the commit, include it to be safe + return [ + 2, + true + ]; + case 4: + return [ + 2 + ]; + } + }); + })(); +}; var collectCommits = function(head, base) { return _async_to_generator(function() { var stats, commitCount, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, commits, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, commit, _exec, _commit_author, message, PR, pull_number, _ref, pr, areas, _iteratorNormalCompletion1, _didIteratorError2, _iteratorError2, _iterator2, _step2, area, e, err, err1; @@ -261,9 +313,9 @@ var collectCommits = function(head, base) { case 1: _state.trys.push([ 1, - 15, 16, - 21 + 17, + 22 ]); _iterator = _async_iterator(context/* octo.paginate.iterator */.NR.paginate.iterator(context/* octo.rest.repos.compareCommits */.NR.rest.repos.compareCommits, { owner: context/* owner */.cR, @@ -281,7 +333,7 @@ var collectCommits = function(head, base) { case 3: if (!(_iteratorAbruptCompletion = !(_step = _state.sent()).done)) return [ 3, - 14 + 15 ]; _value = _step.value; commits = _value.data.commits; @@ -290,16 +342,16 @@ var collectCommits = function(head, base) { case 4: _state.trys.push([ 4, - 11, 12, - 13 + 13, + 14 ]); _iterator1 = commits[Symbol.iterator](); _state.label = 5; case 5: if (!!(_iteratorNormalCompletion = (_step1 = _iterator1.next()).done)) return [ 3, - 10 + 11 ]; commit = _step1.value; if (context/* maxChangelogCommits */.pE > 0 && commitCount >= context/* maxChangelogCommits */.pE) { @@ -310,31 +362,43 @@ var collectCommits = function(head, base) { ]; } commitCount++; + return [ + 4, + commitTouchesWorkingDir(commit.sha) + ]; + case 6: + // Skip commits that don't touch files in the working directory + if (!_state.sent()) { + return [ + 3, + 10 + ]; + } message = commit.commit.message.split('\n')[0]; PR = (_exec = /\(#(\d+)\)$/.exec(message)) === null || _exec === void 0 ? void 0 : _exec[1]; if (!PR) return [ 3, - 9 + 10 ]; pull_number = parseInt(PR); if ((_commit_author = commit.author) === null || _commit_author === void 0 ? void 0 : _commit_author.login) { if ((0,is_action_user/* default */.Z)(commit.author) && message.startsWith('release ')) return [ 3, - 9 + 10 ]; if (message.startsWith('(turbo-module): ')) return [ 3, - 9 + 10 ]; stats.authors.add(commit.author.login); } - _state.label = 6; - case 6: + _state.label = 7; + case 7: _state.trys.push([ - 6, - 8, + 7, + 9, , - 9 + 10 ]); return [ 4, @@ -344,7 +408,7 @@ var collectCommits = function(head, base) { pull_number: pull_number }) ]; - case 7: + case 8: _ref = _state.sent(), pr = _ref.data; areas = pr.labels.filter(function(param) { var name = param.name; @@ -377,37 +441,37 @@ var collectCommits = function(head, base) { } return [ 3, - 9 + 10 ]; - case 8: + case 9: e = _state.sent(); // PR might not exist in this repo (e.g., monorepo with commits from other repos) console.log("Skipping PR #".concat(pull_number, " - not found in this repo")); addPull(stats.pulls, 'general', pull_number, message); return [ 3, - 9 + 10 ]; - case 9: + case 10: _iteratorNormalCompletion = true; return [ 3, 5 ]; - case 10: + case 11: return [ 3, - 13 + 14 ]; - case 11: + case 12: err = _state.sent(); _didIteratorError1 = true; _iteratorError1 = err; return [ 3, - 13 + 14 ]; - case 12: + case 13: try { if (!_iteratorNormalCompletion && _iterator1.return != null) { _iterator1.return(); @@ -420,60 +484,60 @@ var collectCommits = function(head, base) { return [ 7 ]; - case 13: + case 14: _iteratorAbruptCompletion = false; return [ 3, 2 ]; - case 14: + case 15: return [ 3, - 21 + 22 ]; - case 15: + case 16: err1 = _state.sent(); _didIteratorError = true; _iteratorError = err1; return [ 3, - 21 + 22 ]; - case 16: + case 17: _state.trys.push([ - 16, + 17, , - 19, - 20 + 20, + 21 ]); if (!(_iteratorAbruptCompletion && _iterator.return != null)) return [ 3, - 18 + 19 ]; return [ 4, _iterator.return() ]; - case 17: - _state.sent(); - _state.label = 18; case 18: + _state.sent(); + _state.label = 19; + case 19: return [ 3, - 20 + 21 ]; - case 19: + case 20: if (_didIteratorError) { throw _iteratorError; } return [ 7 ]; - case 20: + case 21: return [ 7 ]; - case 21: + case 22: return [ 2, stats diff --git a/packages/action/src/util/collect-commits.ts b/packages/action/src/util/collect-commits.ts index c8f0c4e..82dad30 100644 --- a/packages/action/src/util/collect-commits.ts +++ b/packages/action/src/util/collect-commits.ts @@ -1,4 +1,4 @@ -import { octo, owner, repo, maxChangelogCommits } from '../context'; +import { octo, owner, repo, maxChangelogCommits, workingDirectory } from '../context'; import isActionUser from './is-action-user'; import { ReleasePulls, ReleaseStats } from './types'; @@ -12,6 +12,28 @@ const addPull = ( pulls[type].push({ number, title }); }; +// Check if a commit touches files in the working directory +const commitTouchesWorkingDir = async (sha: string): Promise => { + if (workingDirectory === '.') return true; // No filtering needed for root + + try { + const { data: commit } = await octo.rest.repos.getCommit({ + owner, + repo, + ref: sha, + }); + + const touchesDir = commit.files?.some(file => + file.filename.startsWith(`${workingDirectory}/`) + ) ?? false; + + return touchesDir; + } catch (e) { + // If we can't fetch the commit, include it to be safe + return true; + } +}; + const collectCommits = async (head: string, base: string) => { const stats: ReleaseStats = { authors: new Set(), @@ -33,6 +55,12 @@ const collectCommits = async (head: string, base: string) => { return stats; } commitCount++; + + // Skip commits that don't touch files in the working directory + if (!(await commitTouchesWorkingDir(commit.sha))) { + continue; + } + const message = commit.commit.message.split('\n')[0]; const PR = /\(#(\d+)\)$/.exec(message)?.[1]; if (!PR) continue; From 3c7585f25fefbd09b2838a69deba96e1b67bdfae Mon Sep 17 00:00:00 2001 From: Jack Sharkey Date: Sat, 27 Dec 2025 19:40:56 +0900 Subject: [PATCH 5/8] feat: improve release PRs - Include version in PR title (e.g., "Release v0.0.6-beta.0") - Create PRs as drafts by default - Show commits in descending order (newest first) - Update stale PR detection to use branch pattern --- packages/action/out/174.index.js | 29 ++++++++++++---------- packages/action/out/607.index.js | 29 ++++++++++++---------- packages/action/out/767.index.js | 2 +- packages/action/src/release-pull/create.ts | 19 ++++++++------ packages/action/src/release-pull/shared.ts | 9 ++++--- packages/action/src/util/get-message.ts | 6 ++++- 6 files changed, 56 insertions(+), 38 deletions(-) diff --git a/packages/action/out/174.index.js b/packages/action/out/174.index.js index b3fac05..295602c 100644 --- a/packages/action/out/174.index.js +++ b/packages/action/out/174.index.js @@ -251,12 +251,10 @@ function _ts_generator(thisArg, body) { var runAction = function() { return _async_to_generator(function() { - var fullReleaseTitle, prereleaseTitle, stale, stalePrerelease, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, pulls, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, pull, err, _ref, prereleasePull, fullPull; + var stale, stalePrerelease, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, pulls, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, pull, err, _ref, prereleasePull, fullPull; return _ts_generator(this, function(_state) { switch(_state.label){ case 0: - fullReleaseTitle = (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getFullReleaseTitle */ .n)(); - prereleaseTitle = (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getPrereleaseTitle */ .e)(); stale = []; stalePrerelease = []; _iteratorAbruptCompletion = false, _didIteratorError = false; @@ -293,9 +291,13 @@ var runAction = function() { try { for(_iterator1 = pulls[Symbol.iterator](); !(_iteratorNormalCompletion = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion = true){ pull = _step1.value; - if ((0,_util_is_action_user__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z)(pull.user)) { - if (fullReleaseTitle === pull.title) stale.push(pull); - else if (prereleaseTitle === pull.title) stalePrerelease.push(pull); + // Match by branch pattern instead of title (titles now include versions) + if ((0,_util_is_action_user__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z)(pull.user) && pull.head.ref.startsWith('turbo-module/release-')) { + if (pull.head.ref.includes("-".concat(_context__WEBPACK_IMPORTED_MODULE_1__/* .prereleaseType */ .kD))) { + stalePrerelease.push(pull); + } else { + stale.push(pull); + } } } } catch (err) { @@ -468,11 +470,10 @@ var pull_labels = [ ]; var createPull = function(prerelease) { return _async_to_generator(function() { - var title, releaseLabel, primaryVersionFile, _ref, content, packageJson, newVersion, _ref1, _ref_data, sha, shortSha, branch, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, versionFile, filePath, _ref2, fileContent, filePackageJson, err, message, _ref3, pull, _$err, e; + var releaseLabel, primaryVersionFile, _ref, content, packageJson, newVersion, title, _ref1, _ref_data, sha, shortSha, branch, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, versionFile, filePath, _ref2, fileContent, filePackageJson, err, message, _ref3, pull, _$err, e; return _ts_generator(this, function(_state) { switch(_state.label){ case 0: - title = prerelease ? (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getPrereleaseTitle */ .e)() : (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getFullReleaseTitle */ .n)(); releaseLabel = prerelease ? "releases: ".concat(_context__WEBPACK_IMPORTED_MODULE_1__/* .prereleaseType */ .kD) : 'releases: patch'; // Get the first version file to determine current version primaryVersionFile = (0,_context__WEBPACK_IMPORTED_MODULE_1__/* .withWorkingDir */ .QV)(_context__WEBPACK_IMPORTED_MODULE_1__/* .versionFiles[0] */ .dm[0]); @@ -494,6 +495,7 @@ var createPull = function(prerelease) { newVersion = prerelease ? semver_functions_inc__WEBPACK_IMPORTED_MODULE_0___default()(packageJson.version, 'prerelease', _context__WEBPACK_IMPORTED_MODULE_1__/* .prereleaseType */ .kD) : semver_functions_inc__WEBPACK_IMPORTED_MODULE_0___default()(packageJson.version, 'patch'); } if (!newVersion) throw new Error('Could not increase version'); + title = prerelease ? (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getPrereleaseTitle */ .e)(newVersion) : (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getFullReleaseTitle */ .n)(newVersion); return [ 4, _context__WEBPACK_IMPORTED_MODULE_1__/* .octo.rest.git.getRef */ .NR.rest.git.getRef({ @@ -612,7 +614,8 @@ var createPull = function(prerelease) { title: title, body: message, head: branch, - base: _context__WEBPACK_IMPORTED_MODULE_1__/* .baseBranch */ .a2 + base: _context__WEBPACK_IMPORTED_MODULE_1__/* .baseBranch */ .a2, + draft: true }) ]; case 14: @@ -690,11 +693,11 @@ var createPull = function(prerelease) { /* harmony export */ }); /* harmony import */ var _context__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7501); -var getFullReleaseTitle = function() { - return '(turbo-module): release next version'; +var getFullReleaseTitle = function(version) { + return version ? "Release v".concat(version) : '(turbo-module): release next version'; }; -var getPrereleaseTitle = function() { - return "(turbo-module): release next ".concat(_context__WEBPACK_IMPORTED_MODULE_0__/* .prereleaseType */ .kD, " version"); +var getPrereleaseTitle = function(version) { + return version ? "Release v".concat(version) : "(turbo-module): release next ".concat(_context__WEBPACK_IMPORTED_MODULE_0__/* .prereleaseType */ .kD, " version"); }; diff --git a/packages/action/out/607.index.js b/packages/action/out/607.index.js index d712a17..c07a461 100644 --- a/packages/action/out/607.index.js +++ b/packages/action/out/607.index.js @@ -251,12 +251,10 @@ function _ts_generator(thisArg, body) { var runAction = function() { return _async_to_generator(function() { - var fullReleaseTitle, prereleaseTitle, stale, stalePrerelease, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, pulls, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, pull, err, _ref, prereleasePull, fullPull; + var stale, stalePrerelease, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, pulls, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, pull, err, _ref, prereleasePull, fullPull; return _ts_generator(this, function(_state) { switch(_state.label){ case 0: - fullReleaseTitle = (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getFullReleaseTitle */ .n)(); - prereleaseTitle = (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getPrereleaseTitle */ .e)(); stale = []; stalePrerelease = []; _iteratorAbruptCompletion = false, _didIteratorError = false; @@ -293,9 +291,13 @@ var runAction = function() { try { for(_iterator1 = pulls[Symbol.iterator](); !(_iteratorNormalCompletion = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion = true){ pull = _step1.value; - if ((0,_util_is_action_user__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z)(pull.user)) { - if (fullReleaseTitle === pull.title) stale.push(pull); - else if (prereleaseTitle === pull.title) stalePrerelease.push(pull); + // Match by branch pattern instead of title (titles now include versions) + if ((0,_util_is_action_user__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z)(pull.user) && pull.head.ref.startsWith('turbo-module/release-')) { + if (pull.head.ref.includes("-".concat(_context__WEBPACK_IMPORTED_MODULE_1__/* .prereleaseType */ .kD))) { + stalePrerelease.push(pull); + } else { + stale.push(pull); + } } } } catch (err) { @@ -468,11 +470,10 @@ var pull_labels = [ ]; var createPull = function(prerelease) { return _async_to_generator(function() { - var title, releaseLabel, primaryVersionFile, _ref, content, packageJson, newVersion, _ref1, _ref_data, sha, shortSha, branch, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, versionFile, filePath, _ref2, fileContent, filePackageJson, err, message, _ref3, pull, _$err, e; + var releaseLabel, primaryVersionFile, _ref, content, packageJson, newVersion, title, _ref1, _ref_data, sha, shortSha, branch, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, versionFile, filePath, _ref2, fileContent, filePackageJson, err, message, _ref3, pull, _$err, e; return _ts_generator(this, function(_state) { switch(_state.label){ case 0: - title = prerelease ? (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getPrereleaseTitle */ .e)() : (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getFullReleaseTitle */ .n)(); releaseLabel = prerelease ? "releases: ".concat(_context__WEBPACK_IMPORTED_MODULE_1__/* .prereleaseType */ .kD) : 'releases: patch'; // Get the first version file to determine current version primaryVersionFile = (0,_context__WEBPACK_IMPORTED_MODULE_1__/* .withWorkingDir */ .QV)(_context__WEBPACK_IMPORTED_MODULE_1__/* .versionFiles[0] */ .dm[0]); @@ -494,6 +495,7 @@ var createPull = function(prerelease) { newVersion = prerelease ? semver_functions_inc__WEBPACK_IMPORTED_MODULE_0___default()(packageJson.version, 'prerelease', _context__WEBPACK_IMPORTED_MODULE_1__/* .prereleaseType */ .kD) : semver_functions_inc__WEBPACK_IMPORTED_MODULE_0___default()(packageJson.version, 'patch'); } if (!newVersion) throw new Error('Could not increase version'); + title = prerelease ? (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getPrereleaseTitle */ .e)(newVersion) : (0,_shared__WEBPACK_IMPORTED_MODULE_3__/* .getFullReleaseTitle */ .n)(newVersion); return [ 4, _context__WEBPACK_IMPORTED_MODULE_1__/* .octo.rest.git.getRef */ .NR.rest.git.getRef({ @@ -612,7 +614,8 @@ var createPull = function(prerelease) { title: title, body: message, head: branch, - base: _context__WEBPACK_IMPORTED_MODULE_1__/* .baseBranch */ .a2 + base: _context__WEBPACK_IMPORTED_MODULE_1__/* .baseBranch */ .a2, + draft: true }) ]; case 14: @@ -690,11 +693,11 @@ var createPull = function(prerelease) { /* harmony export */ }); /* harmony import */ var _context__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7501); -var getFullReleaseTitle = function() { - return '(turbo-module): release next version'; +var getFullReleaseTitle = function(version) { + return version ? "Release v".concat(version) : '(turbo-module): release next version'; }; -var getPrereleaseTitle = function() { - return "(turbo-module): release next ".concat(_context__WEBPACK_IMPORTED_MODULE_0__/* .prereleaseType */ .kD, " version"); +var getPrereleaseTitle = function(version) { + return version ? "Release v".concat(version) : "(turbo-module): release next ".concat(_context__WEBPACK_IMPORTED_MODULE_0__/* .prereleaseType */ .kD, " version"); }; diff --git a/packages/action/out/767.index.js b/packages/action/out/767.index.js index df95547..6da8099 100644 --- a/packages/action/out/767.index.js +++ b/packages/action/out/767.index.js @@ -1410,7 +1410,7 @@ var lengthBuffer = 1000; var makeGithubReleaseMessage = function(stats) { var message = "\n".concat(Object.entries(stats.pulls).map(function(param) { var _param = get_message_sliced_to_array(param, 2), key = _param[0], pulls = _param[1]; - return "\n### ".concat(capitalise(key), " Changes\n\n").concat(pulls.map(function(param) { + return "\n### ".concat(capitalise(key), " Changes\n\n").concat(pulls.slice().reverse().map(function(param) { var title = param.title; return "- ".concat(title); }).join('\n'), "\n"); diff --git a/packages/action/src/release-pull/create.ts b/packages/action/src/release-pull/create.ts index 1542745..9ccdde6 100644 --- a/packages/action/src/release-pull/create.ts +++ b/packages/action/src/release-pull/create.ts @@ -14,9 +14,6 @@ import { Pull } from '../util/types'; import { getPrereleaseTitle, getFullReleaseTitle } from './shared'; const runAction = async () => { - const fullReleaseTitle = getFullReleaseTitle(); - const prereleaseTitle = getPrereleaseTitle(); - const stale: Pull[] = []; const stalePrerelease: Pull[] = []; for await (const { data: pulls } of octo.paginate.iterator( @@ -31,9 +28,13 @@ const runAction = async () => { }, )) for (const pull of pulls) { - if (isActionUser(pull.user)) { - if (fullReleaseTitle === pull.title) stale.push(pull); - else if (prereleaseTitle === pull.title) stalePrerelease.push(pull); + // Match by branch pattern instead of title (titles now include versions) + if (isActionUser(pull.user) && pull.head.ref.startsWith('turbo-module/release-')) { + if (pull.head.ref.includes(`-${prereleaseType}`)) { + stalePrerelease.push(pull); + } else { + stale.push(pull); + } } } // close stale PRs and delete the branches @@ -82,7 +83,6 @@ const addCommentToClosed = async (number: number, replacement: number) => { const pull_labels = ['auto-release-pr', 'keep up-to-date']; export const createPull = async (prerelease: boolean) => { - const title = prerelease ? getPrereleaseTitle() : getFullReleaseTitle(); const releaseLabel = prerelease ? `releases: ${prereleaseType}` : 'releases: patch'; @@ -110,6 +110,10 @@ export const createPull = async (prerelease: boolean) => { } if (!newVersion) throw new Error('Could not increase version'); + const title = prerelease + ? getPrereleaseTitle(newVersion) + : getFullReleaseTitle(newVersion); + const { data: { object: { sha }, @@ -171,6 +175,7 @@ export const createPull = async (prerelease: boolean) => { body: message, head: branch, base: baseBranch, + draft: true, }); let err = 0; while (err < 5) { diff --git a/packages/action/src/release-pull/shared.ts b/packages/action/src/release-pull/shared.ts index 27196c4..d917ce4 100644 --- a/packages/action/src/release-pull/shared.ts +++ b/packages/action/src/release-pull/shared.ts @@ -1,5 +1,8 @@ import { prereleaseType } from '../context'; -export const getFullReleaseTitle = () => '(turbo-module): release next version'; -export const getPrereleaseTitle = () => - `(turbo-module): release next ${prereleaseType} version`; +export const getFullReleaseTitle = (version?: string) => + version ? `Release v${version}` : '(turbo-module): release next version'; +export const getPrereleaseTitle = (version?: string) => + version + ? `Release v${version}` + : `(turbo-module): release next ${prereleaseType} version`; diff --git a/packages/action/src/util/get-message.ts b/packages/action/src/util/get-message.ts index 5208765..5b5004b 100644 --- a/packages/action/src/util/get-message.ts +++ b/packages/action/src/util/get-message.ts @@ -18,7 +18,11 @@ ${Object.entries(stats.pulls) ([key, pulls]) => ` ### ${capitalise(key)} Changes -${pulls.map(({ title }) => `- ${title}`).join('\n')} +${pulls + .slice() + .reverse() + .map(({ title }) => `- ${title}`) + .join('\n')} `, ) .join('')} From e2cfbc220e4524cec9ace1ea911d9631370c0f7a Mon Sep 17 00:00:00 2001 From: Jack Sharkey Date: Sat, 27 Dec 2025 19:43:44 +0900 Subject: [PATCH 6/8] feat: add pr-title-prefix input for customizable PR titles Titles now follow format: "[Prefix] Beta Release v0.0.6-beta.10" - Prefix is optional and configurable via pr-title-prefix input - Version is always included - Prerelease type is capitalized (e.g., "Beta Release", "Canary Release") --- action.yml | 3 +++ packages/action/out/174.index.js | 10 ++++++++-- packages/action/out/212.index.js | 2 ++ packages/action/out/587.index.js | 2 ++ packages/action/out/607.index.js | 10 ++++++++-- packages/action/out/767.index.js | 2 ++ packages/action/src/context.ts | 1 + packages/action/src/release-pull/shared.ts | 19 +++++++++++++------ 8 files changed, 39 insertions(+), 10 deletions(-) diff --git a/action.yml b/action.yml index 2d9b733..30d202e 100644 --- a/action.yml +++ b/action.yml @@ -34,3 +34,6 @@ inputs: max-changelog-commits: description: "Maximum commits to scan for changelog generation (0 = unlimited)" default: "100" + pr-title-prefix: + description: "Prefix for release PR titles (e.g., '[Embedded SDK]')" + default: "" diff --git a/packages/action/out/174.index.js b/packages/action/out/174.index.js index 295602c..56fb807 100644 --- a/packages/action/out/174.index.js +++ b/packages/action/out/174.index.js @@ -693,11 +693,17 @@ var createPull = function(prerelease) { /* harmony export */ }); /* harmony import */ var _context__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7501); +var formatTitle = function(releaseType, version) { + var prefix = _context__WEBPACK_IMPORTED_MODULE_0__/* .prTitlePrefix */ .hJ ? "".concat(_context__WEBPACK_IMPORTED_MODULE_0__/* .prTitlePrefix */ .hJ, " ") : ''; + var versionSuffix = version ? " v".concat(version) : ''; + return "".concat(prefix).concat(releaseType).concat(versionSuffix).trim(); +}; var getFullReleaseTitle = function(version) { - return version ? "Release v".concat(version) : '(turbo-module): release next version'; + return formatTitle('Stable Release', version); }; var getPrereleaseTitle = function(version) { - return version ? "Release v".concat(version) : "(turbo-module): release next ".concat(_context__WEBPACK_IMPORTED_MODULE_0__/* .prereleaseType */ .kD, " version"); + var releaseType = _context__WEBPACK_IMPORTED_MODULE_0__/* .prereleaseType.charAt */ .kD.charAt(0).toUpperCase() + _context__WEBPACK_IMPORTED_MODULE_0__/* .prereleaseType.slice */ .kD.slice(1); + return formatTitle("".concat(releaseType, " Release"), version); }; diff --git a/packages/action/out/212.index.js b/packages/action/out/212.index.js index c9377d9..7bfdf3e 100644 --- a/packages/action/out/212.index.js +++ b/packages/action/out/212.index.js @@ -1016,6 +1016,7 @@ var checkPackages = function(rootVersion) { /* harmony export */ "a2": () => (/* binding */ baseBranch), /* harmony export */ "cR": () => (/* binding */ owner), /* harmony export */ "dm": () => (/* binding */ versionFiles), +/* harmony export */ "hJ": () => (/* binding */ prTitlePrefix), /* harmony export */ "hl": () => (/* binding */ commit_hash), /* harmony export */ "kD": () => (/* binding */ prereleaseType), /* harmony export */ "pE": () => (/* binding */ maxChangelogCommits), @@ -1042,6 +1043,7 @@ var publishPackages = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('p var prereleaseType = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('prerelease-type') || 'canary'; var baseBranch = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('base-branch') || 'main'; var maxChangelogCommits = parseInt((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('max-changelog-commits') || '100', 10); +var prTitlePrefix = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('pr-title-prefix') || ''; // Helper to join working directory with a path var withWorkingDir = function(path) { if (workingDirectory === '.') return path; diff --git a/packages/action/out/587.index.js b/packages/action/out/587.index.js index a2da5d6..15d5e35 100644 --- a/packages/action/out/587.index.js +++ b/packages/action/out/587.index.js @@ -17,6 +17,7 @@ exports.modules = { /* harmony export */ "a2": () => (/* binding */ baseBranch), /* harmony export */ "cR": () => (/* binding */ owner), /* harmony export */ "dm": () => (/* binding */ versionFiles), +/* harmony export */ "hJ": () => (/* binding */ prTitlePrefix), /* harmony export */ "hl": () => (/* binding */ commit_hash), /* harmony export */ "kD": () => (/* binding */ prereleaseType), /* harmony export */ "pE": () => (/* binding */ maxChangelogCommits), @@ -43,6 +44,7 @@ var publishPackages = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('p var prereleaseType = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('prerelease-type') || 'canary'; var baseBranch = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('base-branch') || 'main'; var maxChangelogCommits = parseInt((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('max-changelog-commits') || '100', 10); +var prTitlePrefix = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('pr-title-prefix') || ''; // Helper to join working directory with a path var withWorkingDir = function(path) { if (workingDirectory === '.') return path; diff --git a/packages/action/out/607.index.js b/packages/action/out/607.index.js index c07a461..f3c8189 100644 --- a/packages/action/out/607.index.js +++ b/packages/action/out/607.index.js @@ -693,11 +693,17 @@ var createPull = function(prerelease) { /* harmony export */ }); /* harmony import */ var _context__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7501); +var formatTitle = function(releaseType, version) { + var prefix = _context__WEBPACK_IMPORTED_MODULE_0__/* .prTitlePrefix */ .hJ ? "".concat(_context__WEBPACK_IMPORTED_MODULE_0__/* .prTitlePrefix */ .hJ, " ") : ''; + var versionSuffix = version ? " v".concat(version) : ''; + return "".concat(prefix).concat(releaseType).concat(versionSuffix).trim(); +}; var getFullReleaseTitle = function(version) { - return version ? "Release v".concat(version) : '(turbo-module): release next version'; + return formatTitle('Stable Release', version); }; var getPrereleaseTitle = function(version) { - return version ? "Release v".concat(version) : "(turbo-module): release next ".concat(_context__WEBPACK_IMPORTED_MODULE_0__/* .prereleaseType */ .kD, " version"); + var releaseType = _context__WEBPACK_IMPORTED_MODULE_0__/* .prereleaseType.charAt */ .kD.charAt(0).toUpperCase() + _context__WEBPACK_IMPORTED_MODULE_0__/* .prereleaseType.slice */ .kD.slice(1); + return formatTitle("".concat(releaseType, " Release"), version); }; diff --git a/packages/action/out/767.index.js b/packages/action/out/767.index.js index 6da8099..d02cd08 100644 --- a/packages/action/out/767.index.js +++ b/packages/action/out/767.index.js @@ -17,6 +17,7 @@ exports.modules = { /* harmony export */ "a2": () => (/* binding */ baseBranch), /* harmony export */ "cR": () => (/* binding */ owner), /* harmony export */ "dm": () => (/* binding */ versionFiles), +/* harmony export */ "hJ": () => (/* binding */ prTitlePrefix), /* harmony export */ "hl": () => (/* binding */ commit_hash), /* harmony export */ "kD": () => (/* binding */ prereleaseType), /* harmony export */ "pE": () => (/* binding */ maxChangelogCommits), @@ -43,6 +44,7 @@ var publishPackages = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('p var prereleaseType = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('prerelease-type') || 'canary'; var baseBranch = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('base-branch') || 'main'; var maxChangelogCommits = parseInt((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('max-changelog-commits') || '100', 10); +var prTitlePrefix = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('pr-title-prefix') || ''; // Helper to join working directory with a path var withWorkingDir = function(path) { if (workingDirectory === '.') return path; diff --git a/packages/action/src/context.ts b/packages/action/src/context.ts index 30b28b0..a3d892a 100644 --- a/packages/action/src/context.ts +++ b/packages/action/src/context.ts @@ -28,6 +28,7 @@ export const publishPackages: string[] | undefined = getInput('publish-packages' export const prereleaseType: string = getInput('prerelease-type') || 'canary'; export const baseBranch: string = getInput('base-branch') || 'main'; export const maxChangelogCommits: number = parseInt(getInput('max-changelog-commits') || '100', 10); +export const prTitlePrefix: string = getInput('pr-title-prefix') || ''; // Helper to join working directory with a path export const withWorkingDir = (path: string): string => { diff --git a/packages/action/src/release-pull/shared.ts b/packages/action/src/release-pull/shared.ts index d917ce4..f710275 100644 --- a/packages/action/src/release-pull/shared.ts +++ b/packages/action/src/release-pull/shared.ts @@ -1,8 +1,15 @@ -import { prereleaseType } from '../context'; +import { prereleaseType, prTitlePrefix } from '../context'; + +const formatTitle = (releaseType: string, version?: string) => { + const prefix = prTitlePrefix ? `${prTitlePrefix} ` : ''; + const versionSuffix = version ? ` v${version}` : ''; + return `${prefix}${releaseType}${versionSuffix}`.trim(); +}; export const getFullReleaseTitle = (version?: string) => - version ? `Release v${version}` : '(turbo-module): release next version'; -export const getPrereleaseTitle = (version?: string) => - version - ? `Release v${version}` - : `(turbo-module): release next ${prereleaseType} version`; + formatTitle('Stable Release', version); + +export const getPrereleaseTitle = (version?: string) => { + const releaseType = prereleaseType.charAt(0).toUpperCase() + prereleaseType.slice(1); + return formatTitle(`${releaseType} Release`, version); +}; From d08a91c6466422dbe068778303f89c589cdc6d9f Mon Sep 17 00:00:00 2001 From: Jack Sharkey Date: Sat, 27 Dec 2025 20:02:14 +0900 Subject: [PATCH 7/8] feat: add pr-labels input for custom labels on release PRs --- action.yml | 3 +++ packages/action/out/174.index.js | 2 +- packages/action/out/212.index.js | 2 ++ packages/action/out/587.index.js | 2 ++ packages/action/out/607.index.js | 2 +- packages/action/out/767.index.js | 2 ++ packages/action/src/context.ts | 1 + packages/action/src/release-pull/create.ts | 3 ++- 8 files changed, 14 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index 30d202e..be280f2 100644 --- a/action.yml +++ b/action.yml @@ -37,3 +37,6 @@ inputs: pr-title-prefix: description: "Prefix for release PR titles (e.g., '[Embedded SDK]')" default: "" + pr-labels: + description: "JSON array of additional labels to add to release PRs" + default: "[]" diff --git a/packages/action/out/174.index.js b/packages/action/out/174.index.js index 56fb807..356b883 100644 --- a/packages/action/out/174.index.js +++ b/packages/action/out/174.index.js @@ -467,7 +467,7 @@ var addCommentToClosed = function(number, replacement) { var pull_labels = [ 'auto-release-pr', 'keep up-to-date' -]; +].concat(_to_consumable_array(_context__WEBPACK_IMPORTED_MODULE_1__/* .prLabels */ .Zh)); var createPull = function(prerelease) { return _async_to_generator(function() { var releaseLabel, primaryVersionFile, _ref, content, packageJson, newVersion, title, _ref1, _ref_data, sha, shortSha, branch, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, versionFile, filePath, _ref2, fileContent, filePackageJson, err, message, _ref3, pull, _$err, e; diff --git a/packages/action/out/212.index.js b/packages/action/out/212.index.js index 7bfdf3e..37c8b36 100644 --- a/packages/action/out/212.index.js +++ b/packages/action/out/212.index.js @@ -1013,6 +1013,7 @@ var checkPackages = function(rootVersion) { /* harmony export */ "RL": () => (/* binding */ target_comment), /* harmony export */ "RP": () => (/* binding */ publishPackages), /* harmony export */ "Tf": () => (/* binding */ workingDirectory), +/* harmony export */ "Zh": () => (/* binding */ prLabels), /* harmony export */ "a2": () => (/* binding */ baseBranch), /* harmony export */ "cR": () => (/* binding */ owner), /* harmony export */ "dm": () => (/* binding */ versionFiles), @@ -1044,6 +1045,7 @@ var prereleaseType = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('pr var baseBranch = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('base-branch') || 'main'; var maxChangelogCommits = parseInt((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('max-changelog-commits') || '100', 10); var prTitlePrefix = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('pr-title-prefix') || ''; +var prLabels = JSON.parse((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('pr-labels') || '[]'); // Helper to join working directory with a path var withWorkingDir = function(path) { if (workingDirectory === '.') return path; diff --git a/packages/action/out/587.index.js b/packages/action/out/587.index.js index 15d5e35..704e34a 100644 --- a/packages/action/out/587.index.js +++ b/packages/action/out/587.index.js @@ -14,6 +14,7 @@ exports.modules = { /* harmony export */ "RL": () => (/* binding */ target_comment), /* harmony export */ "RP": () => (/* binding */ publishPackages), /* harmony export */ "Tf": () => (/* binding */ workingDirectory), +/* harmony export */ "Zh": () => (/* binding */ prLabels), /* harmony export */ "a2": () => (/* binding */ baseBranch), /* harmony export */ "cR": () => (/* binding */ owner), /* harmony export */ "dm": () => (/* binding */ versionFiles), @@ -45,6 +46,7 @@ var prereleaseType = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('pr var baseBranch = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('base-branch') || 'main'; var maxChangelogCommits = parseInt((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('max-changelog-commits') || '100', 10); var prTitlePrefix = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('pr-title-prefix') || ''; +var prLabels = JSON.parse((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('pr-labels') || '[]'); // Helper to join working directory with a path var withWorkingDir = function(path) { if (workingDirectory === '.') return path; diff --git a/packages/action/out/607.index.js b/packages/action/out/607.index.js index f3c8189..49dc9f9 100644 --- a/packages/action/out/607.index.js +++ b/packages/action/out/607.index.js @@ -467,7 +467,7 @@ var addCommentToClosed = function(number, replacement) { var pull_labels = [ 'auto-release-pr', 'keep up-to-date' -]; +].concat(_to_consumable_array(_context__WEBPACK_IMPORTED_MODULE_1__/* .prLabels */ .Zh)); var createPull = function(prerelease) { return _async_to_generator(function() { var releaseLabel, primaryVersionFile, _ref, content, packageJson, newVersion, title, _ref1, _ref_data, sha, shortSha, branch, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, versionFile, filePath, _ref2, fileContent, filePackageJson, err, message, _ref3, pull, _$err, e; diff --git a/packages/action/out/767.index.js b/packages/action/out/767.index.js index d02cd08..7ac6296 100644 --- a/packages/action/out/767.index.js +++ b/packages/action/out/767.index.js @@ -14,6 +14,7 @@ exports.modules = { /* harmony export */ "RL": () => (/* binding */ target_comment), /* harmony export */ "RP": () => (/* binding */ publishPackages), /* harmony export */ "Tf": () => (/* binding */ workingDirectory), +/* harmony export */ "Zh": () => (/* binding */ prLabels), /* harmony export */ "a2": () => (/* binding */ baseBranch), /* harmony export */ "cR": () => (/* binding */ owner), /* harmony export */ "dm": () => (/* binding */ versionFiles), @@ -45,6 +46,7 @@ var prereleaseType = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('pr var baseBranch = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('base-branch') || 'main'; var maxChangelogCommits = parseInt((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('max-changelog-commits') || '100', 10); var prTitlePrefix = (0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('pr-title-prefix') || ''; +var prLabels = JSON.parse((0,_actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput)('pr-labels') || '[]'); // Helper to join working directory with a path var withWorkingDir = function(path) { if (workingDirectory === '.') return path; diff --git a/packages/action/src/context.ts b/packages/action/src/context.ts index a3d892a..90df871 100644 --- a/packages/action/src/context.ts +++ b/packages/action/src/context.ts @@ -29,6 +29,7 @@ export const prereleaseType: string = getInput('prerelease-type') || 'canary'; export const baseBranch: string = getInput('base-branch') || 'main'; export const maxChangelogCommits: number = parseInt(getInput('max-changelog-commits') || '100', 10); export const prTitlePrefix: string = getInput('pr-title-prefix') || ''; +export const prLabels: string[] = JSON.parse(getInput('pr-labels') || '[]'); // Helper to join working directory with a path export const withWorkingDir = (path: string): string => { diff --git a/packages/action/src/release-pull/create.ts b/packages/action/src/release-pull/create.ts index 9ccdde6..a2d7e3d 100644 --- a/packages/action/src/release-pull/create.ts +++ b/packages/action/src/release-pull/create.ts @@ -7,6 +7,7 @@ import { prereleaseType, baseBranch, withWorkingDir, + prLabels, } from '../context'; import getReleaseMessage from '../util/get-message'; import isActionUser from '../util/is-action-user'; @@ -80,7 +81,7 @@ const addCommentToClosed = async (number: number, replacement: number) => { }); }; -const pull_labels = ['auto-release-pr', 'keep up-to-date']; +const pull_labels = ['auto-release-pr', 'keep up-to-date', ...prLabels]; export const createPull = async (prerelease: boolean) => { const releaseLabel = prerelease From 4a5f430bc93afebb42d1163dc3322175cd426d60 Mon Sep 17 00:00:00 2001 From: Jack Sharkey Date: Sat, 27 Dec 2025 20:14:50 +0900 Subject: [PATCH 8/8] perf: use listCommits with path filter instead of per-commit API calls Much more efficient for monorepos - instead of fetching all commits and checking each one with a separate API call, use the GitHub API's built-in path filter to only retrieve commits touching the working directory. --- packages/action/out/767.index.js | 203 +++++++++----------- packages/action/src/util/collect-commits.ts | 51 ++--- 2 files changed, 108 insertions(+), 146 deletions(-) diff --git a/packages/action/out/767.index.js b/packages/action/out/767.index.js index 7ac6296..75ebff9 100644 --- a/packages/action/out/767.index.js +++ b/packages/action/out/767.index.js @@ -142,6 +142,34 @@ function _async_to_generator(fn) { }); }; } +function _define_property(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + return obj; +} +function _object_spread(target) { + for(var i = 1; i < arguments.length; i++){ + var source = arguments[i] != null ? arguments[i] : {}; + var ownKeys = Object.keys(source); + if (typeof Object.getOwnPropertySymbols === "function") { + ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { + return Object.getOwnPropertyDescriptor(source, sym).enumerable; + })); + } + ownKeys.forEach(function(key) { + _define_property(target, key, source[key]); + }); + } + return target; +} function _ts_generator(thisArg, body) { var f, y, t, _ = { label: 0, @@ -250,60 +278,9 @@ var addPull = function(pulls, type, number, title) { title: title }); }; -// Check if a commit touches files in the working directory -var commitTouchesWorkingDir = function(sha) { - return _async_to_generator(function() { - var _commit_files, _ref, commit, _ref1, touchesDir, e; - return _ts_generator(this, function(_state) { - switch(_state.label){ - case 0: - if (context/* workingDirectory */.Tf === '.') return [ - 2, - true - ]; // No filtering needed for root - _state.label = 1; - case 1: - _state.trys.push([ - 1, - 3, - , - 4 - ]); - return [ - 4, - context/* octo.rest.repos.getCommit */.NR.rest.repos.getCommit({ - owner: context/* owner */.cR, - repo: context/* repo */.O9, - ref: sha - }) - ]; - case 2: - _ref = _state.sent(), commit = _ref.data; - touchesDir = (_ref1 = (_commit_files = commit.files) === null || _commit_files === void 0 ? void 0 : _commit_files.some(function(file) { - return file.filename.startsWith("".concat(context/* workingDirectory */.Tf, "/")); - })) !== null && _ref1 !== void 0 ? _ref1 : false; - return [ - 2, - touchesDir - ]; - case 3: - e = _state.sent(); - // If we can't fetch the commit, include it to be safe - return [ - 2, - true - ]; - case 4: - return [ - 2 - ]; - } - }); - })(); -}; var collectCommits = function(head, base) { return _async_to_generator(function() { - var stats, commitCount, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, commits, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, commit, _exec, _commit_author, message, PR, pull_number, _ref, pr, areas, _iteratorNormalCompletion1, _didIteratorError2, _iteratorError2, _iterator2, _step2, area, e, err, err1; + var stats, commitCount, listOptions, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, commits, _iteratorNormalCompletion, _didIteratorError1, _iteratorError1, _iterator1, _step1, commit, _exec, _commit_author, message, PR, pull_number, _ref, pr, areas, _iteratorNormalCompletion1, _didIteratorError2, _iteratorError2, _iterator2, _step2, area, e, err, err1; return _ts_generator(this, function(_state) { switch(_state.label){ case 0: @@ -312,22 +289,26 @@ var collectCommits = function(head, base) { pulls: {} }; commitCount = 0; + // Use listCommits with path filter for efficiency (only fetches commits touching working dir) + // This is much faster than comparing all commits and checking each one individually + listOptions = _object_spread({ + owner: context/* owner */.cR, + repo: context/* repo */.O9, + sha: head, + per_page: 100 + }, context/* workingDirectory */.Tf !== '.' && { + path: context/* workingDirectory */.Tf + }); _iteratorAbruptCompletion = false, _didIteratorError = false; _state.label = 1; case 1: _state.trys.push([ 1, + 15, 16, - 17, - 22 + 21 ]); - _iterator = _async_iterator(context/* octo.paginate.iterator */.NR.paginate.iterator(context/* octo.rest.repos.compareCommits */.NR.rest.repos.compareCommits, { - owner: context/* owner */.cR, - repo: context/* repo */.O9, - base: base, - head: head, - per_page: 100 - })); + _iterator = _async_iterator(context/* octo.paginate.iterator */.NR.paginate.iterator(context/* octo.rest.repos.listCommits */.NR.rest.repos.listCommits, listOptions)); _state.label = 2; case 2: return [ @@ -337,72 +318,68 @@ var collectCommits = function(head, base) { case 3: if (!(_iteratorAbruptCompletion = !(_step = _state.sent()).done)) return [ 3, - 15 + 14 ]; _value = _step.value; - commits = _value.data.commits; + commits = _value.data; _iteratorNormalCompletion = true, _didIteratorError1 = false, _iteratorError1 = undefined; _state.label = 4; case 4: _state.trys.push([ 4, + 11, 12, - 13, - 14 + 13 ]); _iterator1 = commits[Symbol.iterator](); _state.label = 5; case 5: if (!!(_iteratorNormalCompletion = (_step1 = _iterator1.next()).done)) return [ 3, - 11 + 10 ]; commit = _step1.value; - if (context/* maxChangelogCommits */.pE > 0 && commitCount >= context/* maxChangelogCommits */.pE) { - console.log("Reached max commit limit (".concat(context/* maxChangelogCommits */.pE, "), stopping changelog scan")); + // Stop when we reach the base commit + if (commit.sha === base || commit.sha.startsWith(base) || base.startsWith(commit.sha)) { + console.log("Reached base commit ".concat(base, ", stopping changelog scan")); return [ 2, stats ]; } - commitCount++; - return [ - 4, - commitTouchesWorkingDir(commit.sha) - ]; - case 6: - // Skip commits that don't touch files in the working directory - if (!_state.sent()) { + if (context/* maxChangelogCommits */.pE > 0 && commitCount >= context/* maxChangelogCommits */.pE) { + console.log("Reached max commit limit (".concat(context/* maxChangelogCommits */.pE, "), stopping changelog scan")); return [ - 3, - 10 + 2, + stats ]; } + commitCount++; message = commit.commit.message.split('\n')[0]; PR = (_exec = /\(#(\d+)\)$/.exec(message)) === null || _exec === void 0 ? void 0 : _exec[1]; if (!PR) return [ 3, - 10 + 9 ]; pull_number = parseInt(PR); if ((_commit_author = commit.author) === null || _commit_author === void 0 ? void 0 : _commit_author.login) { if ((0,is_action_user/* default */.Z)(commit.author) && message.startsWith('release ')) return [ 3, - 10 + 9 ]; if (message.startsWith('(turbo-module): ')) return [ 3, - 10 + 9 ]; stats.authors.add(commit.author.login); } - _state.label = 7; - case 7: + _state.label = 6; + case 6: _state.trys.push([ - 7, - 9, + 6, + 8, , - 10 + 9 ]); return [ 4, @@ -412,7 +389,7 @@ var collectCommits = function(head, base) { pull_number: pull_number }) ]; - case 8: + case 7: _ref = _state.sent(), pr = _ref.data; areas = pr.labels.filter(function(param) { var name = param.name; @@ -445,37 +422,37 @@ var collectCommits = function(head, base) { } return [ 3, - 10 + 9 ]; - case 9: + case 8: e = _state.sent(); // PR might not exist in this repo (e.g., monorepo with commits from other repos) console.log("Skipping PR #".concat(pull_number, " - not found in this repo")); addPull(stats.pulls, 'general', pull_number, message); return [ 3, - 10 + 9 ]; - case 10: + case 9: _iteratorNormalCompletion = true; return [ 3, 5 ]; - case 11: + case 10: return [ 3, - 14 + 13 ]; - case 12: + case 11: err = _state.sent(); _didIteratorError1 = true; _iteratorError1 = err; return [ 3, - 14 + 13 ]; - case 13: + case 12: try { if (!_iteratorNormalCompletion && _iterator1.return != null) { _iterator1.return(); @@ -488,60 +465,60 @@ var collectCommits = function(head, base) { return [ 7 ]; - case 14: + case 13: _iteratorAbruptCompletion = false; return [ 3, 2 ]; - case 15: + case 14: return [ 3, - 22 + 21 ]; - case 16: + case 15: err1 = _state.sent(); _didIteratorError = true; _iteratorError = err1; return [ 3, - 22 + 21 ]; - case 17: + case 16: _state.trys.push([ - 17, + 16, , - 20, - 21 + 19, + 20 ]); if (!(_iteratorAbruptCompletion && _iterator.return != null)) return [ 3, - 19 + 18 ]; return [ 4, _iterator.return() ]; - case 18: + case 17: _state.sent(); - _state.label = 19; - case 19: + _state.label = 18; + case 18: return [ 3, - 21 + 20 ]; - case 20: + case 19: if (_didIteratorError) { throw _iteratorError; } return [ 7 ]; - case 21: + case 20: return [ 7 ]; - case 22: + case 21: return [ 2, stats diff --git a/packages/action/src/util/collect-commits.ts b/packages/action/src/util/collect-commits.ts index 82dad30..e913d0c 100644 --- a/packages/action/src/util/collect-commits.ts +++ b/packages/action/src/util/collect-commits.ts @@ -12,55 +12,40 @@ const addPull = ( pulls[type].push({ number, title }); }; -// Check if a commit touches files in the working directory -const commitTouchesWorkingDir = async (sha: string): Promise => { - if (workingDirectory === '.') return true; // No filtering needed for root - - try { - const { data: commit } = await octo.rest.repos.getCommit({ - owner, - repo, - ref: sha, - }); - - const touchesDir = commit.files?.some(file => - file.filename.startsWith(`${workingDirectory}/`) - ) ?? false; - - return touchesDir; - } catch (e) { - // If we can't fetch the commit, include it to be safe - return true; - } -}; - const collectCommits = async (head: string, base: string) => { const stats: ReleaseStats = { authors: new Set(), pulls: {}, }; let commitCount = 0; - for await (const { - data: { commits }, - } of octo.paginate.iterator(octo.rest.repos.compareCommits, { + + // Use listCommits with path filter for efficiency (only fetches commits touching working dir) + // This is much faster than comparing all commits and checking each one individually + const listOptions: Parameters[0] = { owner, repo, - base, - head, + sha: head, per_page: 100, - })) { + ...(workingDirectory !== '.' && { path: workingDirectory }), + }; + + for await (const { data: commits } of octo.paginate.iterator( + octo.rest.repos.listCommits, + listOptions, + )) { for (const commit of commits) { + // Stop when we reach the base commit + if (commit.sha === base || commit.sha.startsWith(base) || base.startsWith(commit.sha)) { + console.log(`Reached base commit ${base}, stopping changelog scan`); + return stats; + } + if (maxChangelogCommits > 0 && commitCount >= maxChangelogCommits) { console.log(`Reached max commit limit (${maxChangelogCommits}), stopping changelog scan`); return stats; } commitCount++; - // Skip commits that don't touch files in the working directory - if (!(await commitTouchesWorkingDir(commit.sha))) { - continue; - } - const message = commit.commit.message.split('\n')[0]; const PR = /\(#(\d+)\)$/.exec(message)?.[1]; if (!PR) continue;