From 4a872bda22a76856885d8040685b7c594e68b5f1 Mon Sep 17 00:00:00 2001 From: Maciej Krajowski-Kukiel Date: Fri, 21 Aug 2026 11:00:58 +0200 Subject: [PATCH] simplify on modules --- .../public/lib/commands/events/publish.liquid | 4 +- .../core/public/lib/commands/hook/fire.liquid | 4 +- .../public/lib/helpers/redirect_to.liquid | 10 +- .../partials/lib/commands/hook/fire.liquid | 4 +- .../user_invited/send_invite_email.liquid | 6 +- .../admin_pages/invite_users/index.liquid | 6 +- .../views/partials/user_invites/form.liquid | 10 +- .../role_permissions/permissions.liquid | 14 +- .../public/lib/commands/session/create.liquid | 12 +- .../public/lib/commands/user/create.liquid | 4 +- .../lib/commands/user/create/build.liquid | 9 +- .../lib/helpers/can_do_or_unauthorized.liquid | 8 +- .../public/lib/queries/profiles/find.liquid | 12 +- .../role_permissions/permissions.liquid | 14 +- scripts/release.mjs | 128 +++++++----------- 15 files changed, 105 insertions(+), 140 deletions(-) diff --git a/pos-module-core/modules/core/public/lib/commands/events/publish.liquid b/pos-module-core/modules/core/public/lib/commands/events/publish.liquid index 586ad27a..8f4622c2 100644 --- a/pos-module-core/modules/core/public/lib/commands/events/publish.liquid +++ b/pos-module-core/modules/core/public/lib/commands/events/publish.liquid @@ -1,8 +1,8 @@ {% doc %} @param {object} object - The object to process @param {string} type - The type identifier - @param {number} delay - Delay in minutes before processing - @param {number} max_attempts - Maximum number of retry attempts + @param {number} [delay] - Deprecated; set metadata.delay in the consumer file instead + @param {number} [max_attempts] - Deprecated; set metadata.max_attempts in the consumer file instead {% enddoc %} {% liquid if delay > 0 diff --git a/pos-module-core/modules/core/public/lib/commands/hook/fire.liquid b/pos-module-core/modules/core/public/lib/commands/hook/fire.liquid index 0b35c386..8c3bb33e 100644 --- a/pos-module-core/modules/core/public/lib/commands/hook/fire.liquid +++ b/pos-module-core/modules/core/public/lib/commands/hook/fire.liquid @@ -1,7 +1,7 @@ {% doc %} @param {string} hook - The hook name without hook_ prefix - @param {object} params - Parameters to pass to the hook - @param {boolean} merge_to_object - If true, merge results into one object instead of collecting in an array + @param {object} [params] - Parameters to pass to the hook + @param {boolean} [merge_to_object] - If true, merge results into one object instead of collecting in an array {% enddoc %} {% liquid if merge_to_object diff --git a/pos-module-core/modules/core/public/lib/helpers/redirect_to.liquid b/pos-module-core/modules/core/public/lib/helpers/redirect_to.liquid index de442587..263dfb0a 100644 --- a/pos-module-core/modules/core/public/lib/helpers/redirect_to.liquid +++ b/pos-module-core/modules/core/public/lib/helpers/redirect_to.liquid @@ -1,10 +1,10 @@ {% doc %} - @param {string} error - The error flash message - @param {string} info - The info flash message - @param {string} notice - The notice flash message - @param {object} object - The object to process + @param {string} [error] - The error flash message + @param {string} [info] - The info flash message + @param {string} [notice] - The notice flash message + @param {object} [object] - The object to process @param {string} [default] - The default value - @param {string} format - The response format + @param {string} [format] - The response format @param {string} [url] - The URL to redirect to {% enddoc %} {% liquid diff --git a/pos-module-core/modules/core/public/views/partials/lib/commands/hook/fire.liquid b/pos-module-core/modules/core/public/views/partials/lib/commands/hook/fire.liquid index 48cd149d..e0dfd0be 100644 --- a/pos-module-core/modules/core/public/views/partials/lib/commands/hook/fire.liquid +++ b/pos-module-core/modules/core/public/views/partials/lib/commands/hook/fire.liquid @@ -1,7 +1,7 @@ {% doc %} @param {string} hook - The hook name without hook_ prefix - @param {object} params - Parameters to pass to the hook - @param {boolean} merge_to_object - If true, merge results into one object instead of collecting in an array + @param {object} [params] - Parameters to pass to the hook + @param {boolean} [merge_to_object] - If true, merge results into one object instead of collecting in an array {% enddoc %} {% liquid if merge_to_object diff --git a/pos-module-user-invites/modules/user_invites/public/lib/consumers/user_invited/send_invite_email.liquid b/pos-module-user-invites/modules/user_invites/public/lib/consumers/user_invited/send_invite_email.liquid index 0a61b00e..6e2bb9ce 100644 --- a/pos-module-user-invites/modules/user_invites/public/lib/consumers/user_invited/send_invite_email.liquid +++ b/pos-module-user-invites/modules/user_invites/public/lib/consumers/user_invited/send_invite_email.liquid @@ -4,10 +4,8 @@ assign user_invite_token = g.users.results.first.token - assign object = {} - assign object['email'] = email - assign object['user_id'] = user_id - assign object['sign_up_url'] = "https://" | append: app_host | append: "/user_invites/" | append: user_invite_id | append: "/edit" | append: "?token=" | append: user_invite_token + assign sign_up_url = "https://" | append: app_host | append: "/user_invites/" | append: user_invite_id | append: "/edit" | append: "?token=" | append: user_invite_token + assign object = { "email": email, "user_id": user_id, "sign_up_url": sign_up_url } assign now_time = 'now' | to_time: 'UTC' assign sent_at = now_time | strftime: "%Y-%m-%dT%H:%M:%S%Z" diff --git a/pos-module-user-invites/modules/user_invites/public/views/partials/admin_pages/invite_users/index.liquid b/pos-module-user-invites/modules/user_invites/public/views/partials/admin_pages/invite_users/index.liquid index 97405765..5840d7ca 100644 --- a/pos-module-user-invites/modules/user_invites/public/views/partials/admin_pages/invite_users/index.liquid +++ b/pos-module-user-invites/modules/user_invites/public/views/partials/admin_pages/invite_users/index.liquid @@ -3,6 +3,8 @@ and a paginated list of past CSV imports. Required: invite_csvs (search result), page (current page number), context {% endcomment %} +{% comment %}theme_render_rc components are provided by the host app's theme, so the linter can never resolve them{% endcomment %} +{% # platformos-check-disable MissingPartial %} {% liquid assign unnamed_label = 'modules/user_invites/admin.invite_users.unnamed' | t %} @@ -50,9 +52,7 @@ if record.status == 'sent' assign chip_variant = 'success' endif - # platformos-check-disable MissingPartial theme_render_rc 'components/molecules/chip', variant: chip_variant, content: record.status - # platformos-check-enable MissingPartial %} @@ -71,9 +71,7 @@ assign url_params = null | hash_merge: page: '' assign url_template = '/admin/community/invite_users{?page}' assign pager_url = url_template | expand_url_template: url_params - # platformos-check-disable MissingPartial theme_render_rc 'components/molecules/pagination', count: invite_csvs.total_pages, active: page, url: pager_url - # platformos-check-enable MissingPartial endif %} diff --git a/pos-module-user-invites/modules/user_invites/public/views/partials/user_invites/form.liquid b/pos-module-user-invites/modules/user_invites/public/views/partials/user_invites/form.liquid index 189e543d..441091ad 100644 --- a/pos-module-user-invites/modules/user_invites/public/views/partials/user_invites/form.liquid +++ b/pos-module-user-invites/modules/user_invites/public/views/partials/user_invites/form.liquid @@ -7,6 +7,8 @@ @param [errors] {object} - per-field error messages @param context {object} - request context (for authenticity_token) {% enddoc %} +{% comment %}theme_render_rc components are provided by the host app's theme, so the linter can never resolve them{% endcomment %} +{% # platformos-check-disable MissingPartial %}

{{ 'modules/user_invites/user_invites.form.title' | t: site_name: site_name }}

@@ -30,18 +32,12 @@ assign label_params = null | hash_merge: content: field.label assign field_params = null | hash_merge: validation: validation, input_params: input_params, label_params: label_params, classes: 'mb-6' - # platformos-check-disable MissingPartial theme_render_rc 'components/molecules/formfield', params: field_params - # platformos-check-enable MissingPartial %} {% endfor %}
- {% liquid - # platformos-check-disable MissingPartial - theme_render_rc 'components/atoms/button', content: "Sign Up", type: 'submit' - # platformos-check-enable MissingPartial - %} + {% theme_render_rc 'components/atoms/button', content: "Sign Up", type: 'submit' %}
diff --git a/pos-module-user/app/modules/user/public/lib/queries/role_permissions/permissions.liquid b/pos-module-user/app/modules/user/public/lib/queries/role_permissions/permissions.liquid index 8fc98277..800df325 100644 --- a/pos-module-user/app/modules/user/public/lib/queries/role_permissions/permissions.liquid +++ b/pos-module-user/app/modules/user/public/lib/queries/role_permissions/permissions.liquid @@ -1,18 +1,16 @@ {% liquid - assign data = {} - assign default_role = context.constants.USER_DEFAULT_ROLE - if default_role != blank - assign data[default_role] = [] - endif - - assign permissions = { + assign data = { "anonymous": ["sessions.create", "users.register"], "authenticated": ["sessions.destroy", "oauth.manage"], "admin": ["admin_pages.view", "admin.users.manage", "users.impersonate"], "member": ["profile.manage"], "superadmin": ["users.impersonate_superadmin"] } - assign data = data | hash_merge: permissions + + assign default_role = context.constants.USER_DEFAULT_ROLE + if default_role != blank and data[default_role] == null + assign data[default_role] = [] + endif return data %} diff --git a/pos-module-user/modules/user/public/lib/commands/session/create.liquid b/pos-module-user/modules/user/public/lib/commands/session/create.liquid index b86b984a..46b559d5 100644 --- a/pos-module-user/modules/user/public/lib/commands/session/create.liquid +++ b/pos-module-user/modules/user/public/lib/commands/session/create.liquid @@ -1,10 +1,10 @@ {% doc %} - @param {string} email - The email address - @param {object} hook_params - Additional parameters to pass to hooks - @param {string} password - The password - @param {boolean} skip_otp - Whether to skip OTP verification - @param {string} user_id - The user ID (used when validate_password is false) - @param {boolean} validate_password - Whether to validate the password + @param {string} [email] - The email address; required unless validate_password is false + @param {object} [hook_params] - Additional parameters to pass to hooks + @param {string} [password] - The password; required unless validate_password is false + @param {boolean} [skip_otp] - Whether to skip OTP verification (default: false) + @param {string} [user_id] - The user ID; required when validate_password is false + @param {boolean} [validate_password] - Whether to validate the password (default: true) {% enddoc %} {% liquid if validate_password == nil diff --git a/pos-module-user/modules/user/public/lib/commands/user/create.liquid b/pos-module-user/modules/user/public/lib/commands/user/create.liquid index 9ebe3bb3..d9a1dc1d 100644 --- a/pos-module-user/modules/user/public/lib/commands/user/create.liquid +++ b/pos-module-user/modules/user/public/lib/commands/user/create.liquid @@ -1,10 +1,10 @@ {% doc %} @param {string} email - The email address @param {string} first_name - The first name - @param {object} hook_params - Additional parameters to pass to hooks + @param {object} [hook_params] - Additional parameters to pass to hooks @param {string} last_name - The last name @param {string} password - The password - @param roles - The roles to assign; a comma separated string or an array + @param [roles] - The roles to assign; a comma separated string or an array {% enddoc %} {% liquid function object = 'modules/user/commands/user/create/build', first_name: first_name, last_name: last_name, email: email, password: password, hook_params: hook_params, roles: roles diff --git a/pos-module-user/modules/user/public/lib/commands/user/create/build.liquid b/pos-module-user/modules/user/public/lib/commands/user/create/build.liquid index 5cae478f..e14430a1 100644 --- a/pos-module-user/modules/user/public/lib/commands/user/create/build.liquid +++ b/pos-module-user/modules/user/public/lib/commands/user/create/build.liquid @@ -1,10 +1,10 @@ {% doc %} @param {string} email - The email address @param {string} first_name - The first name - @param {object} hook_params - Additional parameters to pass to hooks + @param {object} [hook_params] - Additional parameters to pass to hooks @param {string} last_name - The last name @param {string} password - The password - @param roles - The roles to assign; a comma separated string or an array + @param [roles] - The roles to assign; a comma separated string or an array {% enddoc %} {% assign object = { @@ -12,10 +12,9 @@ "last_name": last_name, "email": email, "password": password, - "hook_params": hook_params + "hook_params": hook_params, + "roles": roles } %} -{% assign object.roles = roles %} - {% return object %} diff --git a/pos-module-user/modules/user/public/lib/helpers/can_do_or_unauthorized.liquid b/pos-module-user/modules/user/public/lib/helpers/can_do_or_unauthorized.liquid index 5db63eb1..969a3619 100644 --- a/pos-module-user/modules/user/public/lib/helpers/can_do_or_unauthorized.liquid +++ b/pos-module-user/modules/user/public/lib/helpers/can_do_or_unauthorized.liquid @@ -1,10 +1,10 @@ {% doc %} - @param {string} access_callback - Custom authorization callback path + @param {string} [access_callback] - Custom authorization callback path @param {string} [anonymous_return_to] - URL to redirect anonymous users to @param {string} do - The permission to check - @param {object} entity - The entity to check access against - @param {string} forbidden_partial - Custom partial to render for forbidden access - @param {boolean} redirect_anonymous_to_login - Whether to redirect anonymous users to login + @param {object} [entity] - The entity to check access against + @param {string} [forbidden_partial] - Custom partial to render for forbidden access + @param {boolean} [redirect_anonymous_to_login] - Whether to redirect anonymous users to login @param {object} requester - The user profile requesting access {% enddoc %} {% liquid diff --git a/pos-module-user/modules/user/public/lib/queries/profiles/find.liquid b/pos-module-user/modules/user/public/lib/queries/profiles/find.liquid index a997b5c0..92cb52eb 100644 --- a/pos-module-user/modules/user/public/lib/queries/profiles/find.liquid +++ b/pos-module-user/modules/user/public/lib/queries/profiles/find.liquid @@ -1,9 +1,11 @@ {% doc %} - @param {string} first_name - The first name - @param {string} id - The record ID - @param {string} last_name - The last name - @param {string} user_id - The user ID - @param {string} uuid - The UUID identifier + At least one of id, user_id, or uuid must be given. + + @param {string} [first_name] - The first name + @param {string} [id] - The record ID + @param {string} [last_name] - The last name + @param {string} [user_id] - The user ID + @param {string} [uuid] - The UUID identifier {% enddoc %} {% liquid if user_id == blank and id == blank and uuid == blank diff --git a/pos-module-user/modules/user/public/lib/queries/role_permissions/permissions.liquid b/pos-module-user/modules/user/public/lib/queries/role_permissions/permissions.liquid index 8fc98277..800df325 100644 --- a/pos-module-user/modules/user/public/lib/queries/role_permissions/permissions.liquid +++ b/pos-module-user/modules/user/public/lib/queries/role_permissions/permissions.liquid @@ -1,18 +1,16 @@ {% liquid - assign data = {} - assign default_role = context.constants.USER_DEFAULT_ROLE - if default_role != blank - assign data[default_role] = [] - endif - - assign permissions = { + assign data = { "anonymous": ["sessions.create", "users.register"], "authenticated": ["sessions.destroy", "oauth.manage"], "admin": ["admin_pages.view", "admin.users.manage", "users.impersonate"], "member": ["profile.manage"], "superadmin": ["users.impersonate_superadmin"] } - assign data = data | hash_merge: permissions + + assign default_role = context.constants.USER_DEFAULT_ROLE + if default_role != blank and data[default_role] == null + assign data[default_role] = [] + endif return data %} diff --git a/scripts/release.mjs b/scripts/release.mjs index e5f0ff49..b44e6ba7 100644 --- a/scripts/release.mjs +++ b/scripts/release.mjs @@ -1,30 +1,14 @@ #!/usr/bin/env node -// Interactive release tool for pos-module-* packages. +// Interactive release tool for pos-module-* packages: pick modules and semver +// bumps in a checklist, then each one is released in dependency order via // -// Lists every pos-module-* directory containing a pos-module.json, lets you -// pick which ones to release and with what semver bump (patch/minor/major, -// or "push only" to publish the current version), then asks for your Partner -// Portal email + password and releases each selected module via: -// -// pos-cli modules update (refresh pos-module.lock.json) +// pos-cli modules update --dev (refresh pos-module.lock.json) // pos-cli modules version --no-git (skipped for "push only") // pos-cli modules push --email (password via POS_PORTAL_PASSWORD) // -// Modules are listed and released in dependency order (topological sort of -// the "dependencies" in each pos-module.json, seeded with common-styling, -// core, user first), so a parent module is always published before its -// dependents and each dependent's lock file picks up the fresh version. -// -// After the release loop, every other module in the repo whose dependencies -// or devDependencies reference a just-released module gets its declared range -// bumped (same-major releases only — e.g. ^0.0.13 → ^0.0.14, since npm caret -// semantics pin ^0.0.x to that exact patch) and its pos-module.lock.json -// refreshed, so the committed locks — and CI's frozen installs — reference -// what was actually published. -// -// Bumps use --no-git because modules share this monorepo's git history and -// pos-cli's per-module tags (e.g. "2.1.11") would collide between modules. -// After a successful run the script offers a single combined git commit. +// followed by a dependency-range/lock sync of the repo's other modules and an +// offer to git-commit the result. See RELEASE.md for the full walkthrough and +// the rationale behind the ordering, the range bumping, and --no-git. // // Requires Node.js >= 20.12 (uses node:util styleText). Usage: // node scripts/release.mjs @@ -63,10 +47,15 @@ const bumpLabel = { push: styleText('cyan', 'push only'), }; +const parseVersion = (version) => { + const match = String(version).match(/^(\d+)\.(\d+)\.(\d+)/); + return match ? match.slice(1).map(Number) : null; +}; + const semverInc = (version, bump) => { - const match = version.match(/^(\d+)\.(\d+)\.(\d+)/); - if (!match) return null; - const [major, minor, patch] = match.slice(1).map(Number); + const parsed = parseVersion(version); + if (!parsed) return null; + const [major, minor, patch] = parsed; switch (bump) { case 'major': return `${major + 1}.0.0`; @@ -79,11 +68,6 @@ const semverInc = (version, bump) => { } }; -const parseVersion = (version) => { - const match = String(version).match(/^(\d+)\.(\d+)\.(\d+)/); - return match ? match.slice(1).map(Number) : null; -}; - const compareVersions = (a, b) => a[0] - b[0] || a[1] - b[1] || a[2] - b[2]; // Minimal matcher for the range shapes used in pos-module.json files @@ -109,21 +93,16 @@ const rangeIncludes = (range, version) => { const escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); -const readManifest = async (dir) => { +const readJson = async (dir, file) => { try { - return JSON.parse(await readFile(path.join(dir, 'pos-module.json'), 'utf8')); + return JSON.parse(await readFile(path.join(dir, file), 'utf8')); } catch { return null; } }; -const readLock = async (dir) => { - try { - return JSON.parse(await readFile(path.join(dir, 'pos-module.lock.json'), 'utf8')); - } catch { - return null; - } -}; +const readManifest = (dir) => readJson(dir, 'pos-module.json'); +const readLock = (dir) => readJson(dir, 'pos-module.lock.json'); const discoverModules = async () => { const entries = (await readdir(ROOT)).filter((name) => name.startsWith('pos-module-')).sort(); @@ -146,10 +125,11 @@ const discoverModules = async () => { return sortByReleaseOrder(modules.filter(Boolean)); }; -// Topological sort by declared dependencies, so parents are released before -// their dependents. Seeded with the foundation modules first so the overall -// order starts: tests, common-styling, core, user, then everything else. -// tests goes first so dependents' lock refreshes pick up its fresh version. +// Topological sort by declared dependencies (devDependencies included), so +// parents are always released before their dependents. The seed order below +// only breaks ties between modules with no dependency relationship — it pins +// the foundation modules to the top of the checklist for readability, while +// correctness comes from the topological sort alone. const FOUNDATION_ORDER = ['tests', 'common-styling', 'core', 'user']; const sortByReleaseOrder = (modules) => { @@ -224,7 +204,9 @@ const abort = () => { process.exit(130); }; -const promptText = (question, defaultValue = '') => +// mask: echo '*' instead of the typed key and return the buffer verbatim +// (no trimming, no default) — used for passwords. +const prompt = (question, { defaultValue = '', mask = false } = {}) => new Promise((resolve) => { const suffix = defaultValue ? styleText('dim', ` [${defaultValue}]`) : ''; process.stdout.write(`${question}${suffix}: `); @@ -234,7 +216,7 @@ const promptText = (question, defaultValue = '') => if (key === '\r' || key === '\n') { process.stdout.write('\n'); stop(); - resolve(buffer.trim() || defaultValue); + resolve(mask ? buffer : buffer.trim() || defaultValue); } else if (key === KEY.backspace || key === '\b') { if (buffer.length) { buffer = buffer.slice(0, -1); @@ -242,32 +224,13 @@ const promptText = (question, defaultValue = '') => } } else if (key >= ' ') { buffer += key; - process.stdout.write(key); + process.stdout.write(mask ? '*' : key); } }); }); -const promptHidden = (question) => - new Promise((resolve) => { - process.stdout.write(`${question}: `); - let buffer = ''; - const stop = readKeys((key) => { - if (key === KEY.ctrlC) abort(); - if (key === '\r' || key === '\n') { - process.stdout.write('\n'); - stop(); - resolve(buffer); - } else if (key === KEY.backspace || key === '\b') { - if (buffer.length) { - buffer = buffer.slice(0, -1); - process.stdout.write('\b \b'); - } - } else if (key >= ' ') { - buffer += key; - process.stdout.write('*'); - } - }); - }); +const promptText = (question, defaultValue = '') => prompt(question, { defaultValue }); +const promptHidden = (question) => prompt(question, { mask: true }); const promptYesNo = async (question) => /^y(es)?$/i.test(await promptText(`${question} (y/N)`)); @@ -346,10 +309,16 @@ const selectModules = (modules) => // 0.0.14). Major jumps are left alone: compatibility must be verified by hand // (see RELEASE.md). const fixDependencyRanges = async (module, released) => { - const manifest = await readManifest(module.dir); - if (!manifest) return; + if (!released.size) return; const file = path.join(module.dir, 'pos-module.json'); - let raw = await readFile(file, 'utf8'); + let raw; + let manifest; + try { + raw = await readFile(file, 'utf8'); + manifest = JSON.parse(raw); + } catch { + return; + } let changed = false; for (const section of ['dependencies', 'devDependencies']) { for (const [dep, range] of Object.entries(manifest[section] ?? {})) { @@ -363,7 +332,12 @@ const fixDependencyRanges = async (module, released) => { continue; } const newRange = `${shape[1]}${release.newVersion}`; - raw = raw.replace(new RegExp(`("${escapeRegExp(dep)}"\\s*:\\s*)"${escapeRegExp(range)}"`), `$1"${newRange}"`); + const next = raw.replace(new RegExp(`("${escapeRegExp(dep)}"\\s*:\\s*)"${escapeRegExp(range)}"`), `$1"${newRange}"`); + if (next === raw) { + console.log(styleText('yellow', ` could not rewrite "${dep}": "${range}" in ${file} — update the range by hand`)); + continue; + } + raw = next; console.log(` ${dep}: range ${range} ${styleText('dim', '→')} ${styleText('bold', newRange)}`); changed = true; } @@ -398,6 +372,9 @@ const syncDependents = async (allModules, released) => { process.stdout.write(`\n${styleText('bold', `── ${module.name} ──`)} ${styleText('dim', '(dependent of a released module)')}\n`); await fixDependencyRanges(module, released); let ok = true; + // Update each stale dependency by name rather than a blanket + // `modules update --dev`, so a module that is not being released only + // picks up versions published in this run, not unrelated newer releases. for (const { dep, flags } of stale) { const update = spawnSync('pos-cli', ['modules', 'update', dep, ...flags], { cwd: module.dir, stdio: 'inherit' }); if (update.status !== 0) ok = false; @@ -420,16 +397,15 @@ const releaseModule = async (module, email, password, released) => { if (update.status !== 0) return { ...module, ok: false, stage: 'dependency update' }; } + let newVersion = module.version; if (module.bump !== 'push') { const bump = spawnSync('pos-cli', ['modules', 'version', module.bump, '--no-git'], { cwd: module.dir, stdio: 'inherit', }); if (bump.status !== 0) return { ...module, ok: false, stage: 'version bump' }; - module.newVersion = (await readManifest(module.dir))?.version ?? semverInc(module.version, module.bump); - console.log(styleText('green', `version bumped to ${module.newVersion}`)); - } else { - module.newVersion = module.version; + newVersion = (await readManifest(module.dir))?.version ?? semverInc(module.version, module.bump); + console.log(styleText('green', `version bumped to ${newVersion}`)); } const push = spawnSync('pos-cli', ['modules', 'push', '--email', email], { @@ -438,7 +414,7 @@ const releaseModule = async (module, email, password, released) => { env: { ...process.env, POS_PORTAL_PASSWORD: password }, }); if (push.status !== 0) return { ...module, ok: false, stage: 'push' }; - return { ...module, ok: true }; + return { ...module, newVersion, ok: true }; }; const offerGitCommit = async (results, synced) => {