From 898e97ed17efe747196bdcd3765f22cac57aa05b Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 22 May 2025 06:55:42 -0700 Subject: [PATCH] fix(cpa): ensure it always installs the latest version of the templates (#12488) CPA would previously install an outdated version of the templates based on the git tag, this is now set to the `main` branch ensuring that the latest version is always installed. --- .../create-payload-app/src/lib/constants.ts | 8 ----- .../create-payload-app/src/lib/templates.ts | 7 ++-- .../src/lib/update-payload-in-project.ts | 13 ++----- packages/create-payload-app/src/main.ts | 15 +++++--- .../src/utils/getLatestPackageVersion.ts | 34 +++++++++++++++++++ 5 files changed, 50 insertions(+), 27 deletions(-) delete mode 100644 packages/create-payload-app/src/lib/constants.ts create mode 100644 packages/create-payload-app/src/utils/getLatestPackageVersion.ts diff --git a/packages/create-payload-app/src/lib/constants.ts b/packages/create-payload-app/src/lib/constants.ts deleted file mode 100644 index d50a3d5a2..000000000 --- a/packages/create-payload-app/src/lib/constants.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { readFileSync } from 'fs' -import { fileURLToPath } from 'node:url' -import path from 'path' -const filename = fileURLToPath(import.meta.url) -const dirname = path.dirname(filename) - -const packageJson = JSON.parse(readFileSync(path.resolve(dirname, '../../package.json'), 'utf-8')) -export const PACKAGE_VERSION = packageJson.version diff --git a/packages/create-payload-app/src/lib/templates.ts b/packages/create-payload-app/src/lib/templates.ts index 0260c3f59..f9d3212cc 100644 --- a/packages/create-payload-app/src/lib/templates.ts +++ b/packages/create-payload-app/src/lib/templates.ts @@ -1,9 +1,8 @@ import type { ProjectTemplate } from '../types.js' import { error, info } from '../utils/log.js' -import { PACKAGE_VERSION } from './constants.js' -export function validateTemplate(templateName: string): boolean { +export function validateTemplate({ templateName }: { templateName: string }): boolean { const validTemplates = getValidTemplates() if (!validTemplates.map((t) => t.name).includes(templateName)) { error(`'${templateName}' is not a valid template.`) @@ -20,13 +19,13 @@ export function getValidTemplates(): ProjectTemplate[] { name: 'blank', type: 'starter', description: 'Blank 3.0 Template', - url: `https://github.com/payloadcms/payload/templates/blank#v${PACKAGE_VERSION}`, + url: `https://github.com/payloadcms/payload/templates/blank#main`, }, { name: 'website', type: 'starter', description: 'Website Template', - url: `https://github.com/payloadcms/payload/templates/website#v${PACKAGE_VERSION}`, + url: `https://github.com/payloadcms/payload/templates/website#main`, }, { name: 'plugin', diff --git a/packages/create-payload-app/src/lib/update-payload-in-project.ts b/packages/create-payload-app/src/lib/update-payload-in-project.ts index f60834f85..bf5b06be6 100644 --- a/packages/create-payload-app/src/lib/update-payload-in-project.ts +++ b/packages/create-payload-app/src/lib/update-payload-in-project.ts @@ -1,4 +1,3 @@ -import execa from 'execa' import fse from 'fs-extra' import { fileURLToPath } from 'node:url' import path from 'path' @@ -9,6 +8,7 @@ const dirname = path.dirname(filename) import type { NextAppDetails } from '../types.js' import { copyRecursiveSync } from '../utils/copy-recursive-sync.js' +import { getLatestPackageVersion } from '../utils/getLatestPackageVersion.js' import { info } from '../utils/log.js' import { getPackageManager } from './get-package-manager.js' import { installPackages } from './install-packages.js' @@ -36,15 +36,8 @@ export async function updatePayloadInProject( const packageManager = await getPackageManager({ projectDir }) - // Fetch latest Payload version from npm - const { exitCode: getLatestVersionExitCode, stdout: latestPayloadVersion } = await execa('npm', [ - 'show', - 'payload', - 'version', - ]) - if (getLatestVersionExitCode !== 0) { - throw new Error('Failed to fetch latest Payload version') - } + // Fetch latest Payload version + const latestPayloadVersion = await getLatestPackageVersion({ packageName: 'payload' }) if (payloadVersion === latestPayloadVersion) { return { message: `Payload v${payloadVersion} is already up to date.`, success: true } diff --git a/packages/create-payload-app/src/main.ts b/packages/create-payload-app/src/main.ts index 38f7c7df1..42601b711 100644 --- a/packages/create-payload-app/src/main.ts +++ b/packages/create-payload-app/src/main.ts @@ -8,7 +8,6 @@ import path from 'path' import type { CliArgs } from './types.js' import { configurePayloadConfig } from './lib/configure-payload-config.js' -import { PACKAGE_VERSION } from './lib/constants.js' import { createProject } from './lib/create-project.js' import { parseExample } from './lib/examples.js' import { generateSecret } from './lib/generate-secret.js' @@ -20,6 +19,7 @@ import { parseTemplate } from './lib/parse-template.js' import { selectDb } from './lib/select-db.js' import { getValidTemplates, validateTemplate } from './lib/templates.js' import { updatePayloadInProject } from './lib/update-payload-in-project.js' +import { getLatestPackageVersion } from './utils/getLatestPackageVersion.js' import { debug, error, info } from './utils/log.js' import { feedbackOutro, @@ -78,13 +78,18 @@ export class Main { async init(): Promise { try { + const debugFlag = this.args['--debug'] + + const LATEST_VERSION = await getLatestPackageVersion({ + debug: debugFlag, + packageName: 'payload', + }) + if (this.args['--help']) { helpMessage() process.exit(0) } - const debugFlag = this.args['--debug'] - // eslint-disable-next-line no-console console.log('\n') p.intro(chalk.bgCyan(chalk.black(' create-payload-app '))) @@ -200,7 +205,7 @@ export class Main { const templateArg = this.args['--template'] if (templateArg) { - const valid = validateTemplate(templateArg) + const valid = validateTemplate({ templateName: templateArg }) if (!valid) { helpMessage() process.exit(1) @@ -230,7 +235,7 @@ export class Main { } if (debugFlag) { - debug(`Using ${exampleArg ? 'examples' : 'templates'} from git tag: v${PACKAGE_VERSION}`) + debug(`Using ${exampleArg ? 'examples' : 'templates'} from git tag: v${LATEST_VERSION}`) } if (!exampleArg) { diff --git a/packages/create-payload-app/src/utils/getLatestPackageVersion.ts b/packages/create-payload-app/src/utils/getLatestPackageVersion.ts new file mode 100644 index 000000000..18fd2478c --- /dev/null +++ b/packages/create-payload-app/src/utils/getLatestPackageVersion.ts @@ -0,0 +1,34 @@ +/** + * Fetches the latest version of a package from the NPM registry. + * + * Used in determining the latest version of Payload to use in the generated templates. + */ +export async function getLatestPackageVersion({ + debug = false, + packageName = 'payload', +}: { + debug?: boolean + /** + * Package name to fetch the latest version for based on the NPM registry URL + * + * Eg. for `'payload'`, it will fetch the version from `https://registry.npmjs.org/payload` + * + * @default 'payload' + */ + packageName?: string +}) { + try { + const response = await fetch(`https://registry.npmjs.org/${packageName}`) + const data = await response.json() + const latestVersion = data['dist-tags'].latest + + if (debug) { + console.log(`Found latest version of ${packageName}: ${latestVersion}`) + } + + return latestVersion + } catch (error) { + console.error('Error fetching Payload version:', error) + throw error + } +}