diff --git a/README.md b/README.md index 914dec7..dd59518 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# discourse-skeleton-update +# @discourse/update-skeleton Update a Discourse theme or plugin's scaffolding and install its dependencies. Requires Node.js 22.13+, pnpm, Ruby, and Bundler. @@ -6,12 +6,12 @@ Requires Node.js 22.13+, pnpm, Ruby, and Bundler. Run from the theme or plugin root: ```sh -pnpx discourse-skeleton-update@latest +pnpx @discourse/update-skeleton@latest ``` -Skeletons also provide `pnpm discourse-skeleton-update`, which runs that command +Skeletons also provide `pnpm update-skeleton`, which runs that command without adding the updater as a dependency. For local development, run -`node /path/to/discourse-skeleton-update/bin/discourse-skeleton-update.js`. +`node /path/to/update-skeleton/bin/update-skeleton.js`. ## What it does @@ -54,7 +54,7 @@ To release, bump `version` in `package.json` and merge to `main`. Already published versions are skipped by `pnpm publish -r`. Configure an [npm trusted publisher](https://docs.npmjs.com/trusted-publishers/) -for the package: organization `discourse`, repository `discourse-skeleton-update`, +for the package: organization `discourse`, repository `update-skeleton`, workflow `ci.yml`, no environment, with direct publishing allowed. No npm token secret is needed. If the package does not exist yet, publish its first version manually before configuring the trusted publisher. diff --git a/bin/discourse-skeleton-update.js b/bin/update-skeleton.js similarity index 79% rename from bin/discourse-skeleton-update.js rename to bin/update-skeleton.js index ce0e811..926de20 100755 --- a/bin/discourse-skeleton-update.js +++ b/bin/update-skeleton.js @@ -8,7 +8,7 @@ try { }); if (values.help) { console.log( - "Run discourse-skeleton-update from a theme or plugin root to replace scaffolding and install dependencies." + "Run update-skeleton from a theme or plugin root to replace scaffolding and install dependencies." ); } else { await update(); diff --git a/package.json b/package.json index 4ab1a85..02019a1 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { - "name": "discourse-skeleton-update", + "name": "@discourse/update-skeleton", "version": "0.1.0", "description": "Update Discourse theme and plugin scaffolding and install its dependencies", "type": "module", "bin": { - "discourse-skeleton-update": "bin/discourse-skeleton-update.js" + "update-skeleton": "bin/update-skeleton.js" }, "files": [ "bin/", @@ -21,7 +21,7 @@ "license": "MIT", "repository": { "type": "git", - "url": "git+https://github.com/discourse/discourse-skeleton-update.git" + "url": "git+https://github.com/discourse/update-skeleton.git" }, "publishConfig": { "access": "public" diff --git a/test/fixtures/plugin.json b/test/fixtures/plugin.json index f504e5c..00a51bf 100644 --- a/test/fixtures/plugin.json +++ b/test/fixtures/plugin.json @@ -2,7 +2,7 @@ "type": "plugin", "repository": "discourse/discourse-plugin-skeleton", "files": { - "package.json": "{\n \"private\": true,\n \"devDependencies\": {\n \"@discourse/lint-configs\": \"3.2.0\",\n \"@glint/ember-tsc\": \"1.8.11\",\n \"concurrently\": \"^9.2.3\",\n \"discourse\": \"npm:@discourse/types@2026.3.0-d02b2966\",\n \"eslint\": \"10.6.0\",\n \"lint-to-the-future\": \"^2.6.4\",\n \"lint-to-the-future-eslint\": \"^3.3.0\",\n \"prettier\": \"3.8.1\",\n \"stylelint\": \"17.5.0\"\n },\n \"scripts\": {\n \"lint\": \"concurrently \\\"pnpm:lint:*(!fix)\\\" --names \\\"lint:\\\"\",\n \"lint:fix\": \"concurrently \\\"pnpm:lint:*:fix\\\" --names \\\"fix:\\\"\",\n \"lint:css\": \"pnpm stylelint 'assets/stylesheets/**/*.scss' --allow-empty-input\",\n \"lint:css:fix\": \"pnpm stylelint 'assets/stylesheets/**/*.scss' --fix --allow-empty-input\",\n \"lint:js\": \"eslint {assets,admin/assets,test}/javascripts --cache --no-error-on-unmatched-pattern\",\n \"lint:js:fix\": \"eslint {assets,admin/assets,test}/javascripts --fix --no-error-on-unmatched-pattern\",\n \"lint:prettier\": \"pnpm prettier 'assets/stylesheets/**/*.scss' '{assets,admin/assets,test}/javascripts/**/*.{js,gjs,ts,gts,mts,cts}' --check --no-error-on-unmatched-pattern\",\n \"lint:prettier:fix\": \"pnpm prettier 'assets/stylesheets/**/*.scss' '{assets,admin/assets,test}/javascripts/**/*.{js,gjs,ts,gts,mts,cts}' -w --no-error-on-unmatched-pattern\",\n \"lint:types\": \"ember-tsc -b\",\n \"lttf:ignore\": \"lint-to-the-future ignore\",\n \"discourse-skeleton-update\": \"pnpx discourse-skeleton-update@latest\"\n },\n \"engines\": {\n \"node\": \">= 22\",\n \"npm\": \"please-use-pnpm\",\n \"yarn\": \"please-use-pnpm\",\n \"pnpm\": \"^10\"\n },\n \"packageManager\": \"pnpm@10.28.0\"\n}\n", + "package.json": "{\n \"private\": true,\n \"devDependencies\": {\n \"@discourse/lint-configs\": \"3.2.0\",\n \"@glint/ember-tsc\": \"1.8.11\",\n \"concurrently\": \"^9.2.3\",\n \"discourse\": \"npm:@discourse/types@2026.3.0-d02b2966\",\n \"eslint\": \"10.6.0\",\n \"lint-to-the-future\": \"^2.6.4\",\n \"lint-to-the-future-eslint\": \"^3.3.0\",\n \"prettier\": \"3.8.1\",\n \"stylelint\": \"17.5.0\"\n },\n \"scripts\": {\n \"lint\": \"concurrently \\\"pnpm:lint:*(!fix)\\\" --names \\\"lint:\\\"\",\n \"lint:fix\": \"concurrently \\\"pnpm:lint:*:fix\\\" --names \\\"fix:\\\"\",\n \"lint:css\": \"pnpm stylelint 'assets/stylesheets/**/*.scss' --allow-empty-input\",\n \"lint:css:fix\": \"pnpm stylelint 'assets/stylesheets/**/*.scss' --fix --allow-empty-input\",\n \"lint:js\": \"eslint {assets,admin/assets,test}/javascripts --cache --no-error-on-unmatched-pattern\",\n \"lint:js:fix\": \"eslint {assets,admin/assets,test}/javascripts --fix --no-error-on-unmatched-pattern\",\n \"lint:prettier\": \"pnpm prettier 'assets/stylesheets/**/*.scss' '{assets,admin/assets,test}/javascripts/**/*.{js,gjs,ts,gts,mts,cts}' --check --no-error-on-unmatched-pattern\",\n \"lint:prettier:fix\": \"pnpm prettier 'assets/stylesheets/**/*.scss' '{assets,admin/assets,test}/javascripts/**/*.{js,gjs,ts,gts,mts,cts}' -w --no-error-on-unmatched-pattern\",\n \"lint:types\": \"ember-tsc -b\",\n \"lttf:ignore\": \"lint-to-the-future ignore\",\n \"update-skeleton\": \"pnpx @discourse/update-skeleton@latest\"\n },\n \"engines\": {\n \"node\": \">= 22\",\n \"npm\": \"please-use-pnpm\",\n \"yarn\": \"please-use-pnpm\",\n \"pnpm\": \"^10\"\n },\n \"packageManager\": \"pnpm@10.28.0\"\n}\n", ".gitignore": "node_modules\n/gems\n/auto_generated\n.eslintcache\n", "eslint.config.mjs": "import DiscourseRecommended from \"@discourse/lint-configs/eslint\";\n\nexport default [...DiscourseRecommended];\n", ".prettierrc.cjs": "module.exports = require(\"@discourse/lint-configs/prettier\");\n", diff --git a/test/fixtures/theme.json b/test/fixtures/theme.json index 36237e6..be6261d 100644 --- a/test/fixtures/theme.json +++ b/test/fixtures/theme.json @@ -2,7 +2,7 @@ "type": "theme", "repository": "discourse/discourse-theme-skeleton", "files": { - "package.json": "{\n \"private\": true,\n \"devDependencies\": {\n \"@discourse/lint-configs\": \"3.2.0\",\n \"@glint/ember-tsc\": \"1.8.11\",\n \"concurrently\": \"^9.2.3\",\n \"discourse\": \"npm:@discourse/types@2026.3.0-d02b2966\",\n \"eslint\": \"10.6.0\",\n \"lint-to-the-future\": \"^2.6.4\",\n \"lint-to-the-future-eslint\": \"^3.3.0\",\n \"prettier\": \"3.8.1\",\n \"stylelint\": \"17.5.0\"\n },\n \"scripts\": {\n \"lint\": \"concurrently \\\"pnpm:lint:*(!fix)\\\" --names \\\"lint:\\\"\",\n \"lint:fix\": \"concurrently \\\"pnpm:lint:*:fix\\\" --names \\\"fix:\\\"\",\n \"lint:css\": \"pnpm stylelint '{javascripts,desktop,mobile,common,scss,stylesheets}/**/*.scss' --allow-empty-input\",\n \"lint:css:fix\": \"pnpm stylelint '{javascripts,desktop,mobile,common,scss,stylesheets}/**/*.scss' --fix --allow-empty-input\",\n \"lint:js\": \"eslint {javascripts,test} --cache --no-error-on-unmatched-pattern\",\n \"lint:js:fix\": \"eslint {javascripts,test} --fix --no-error-on-unmatched-pattern\",\n \"lint:prettier\": \"pnpm prettier '{javascripts,desktop,mobile,common,scss,stylesheets}/**/*.scss' '{javascripts,test}/**/*.{js,gjs,ts,gts,mts,cts}' --check --no-error-on-unmatched-pattern\",\n \"lint:prettier:fix\": \"pnpm prettier '{javascripts,desktop,mobile,common,scss,stylesheets}/**/*.scss' '{javascripts,test}/**/*.{js,gjs,ts,gts,mts,cts}' -w --no-error-on-unmatched-pattern\",\n \"lint:types\": \"ember-tsc -b\",\n \"lttf:ignore\": \"lint-to-the-future ignore\",\n \"discourse-skeleton-update\": \"pnpx discourse-skeleton-update@latest\"\n },\n \"engines\": {\n \"node\": \">= 22\",\n \"npm\": \"please-use-pnpm\",\n \"yarn\": \"please-use-pnpm\",\n \"pnpm\": \"^10\"\n },\n \"packageManager\": \"pnpm@10.28.0\"\n}\n", + "package.json": "{\n \"private\": true,\n \"devDependencies\": {\n \"@discourse/lint-configs\": \"3.2.0\",\n \"@glint/ember-tsc\": \"1.8.11\",\n \"concurrently\": \"^9.2.3\",\n \"discourse\": \"npm:@discourse/types@2026.3.0-d02b2966\",\n \"eslint\": \"10.6.0\",\n \"lint-to-the-future\": \"^2.6.4\",\n \"lint-to-the-future-eslint\": \"^3.3.0\",\n \"prettier\": \"3.8.1\",\n \"stylelint\": \"17.5.0\"\n },\n \"scripts\": {\n \"lint\": \"concurrently \\\"pnpm:lint:*(!fix)\\\" --names \\\"lint:\\\"\",\n \"lint:fix\": \"concurrently \\\"pnpm:lint:*:fix\\\" --names \\\"fix:\\\"\",\n \"lint:css\": \"pnpm stylelint '{javascripts,desktop,mobile,common,scss,stylesheets}/**/*.scss' --allow-empty-input\",\n \"lint:css:fix\": \"pnpm stylelint '{javascripts,desktop,mobile,common,scss,stylesheets}/**/*.scss' --fix --allow-empty-input\",\n \"lint:js\": \"eslint {javascripts,test} --cache --no-error-on-unmatched-pattern\",\n \"lint:js:fix\": \"eslint {javascripts,test} --fix --no-error-on-unmatched-pattern\",\n \"lint:prettier\": \"pnpm prettier '{javascripts,desktop,mobile,common,scss,stylesheets}/**/*.scss' '{javascripts,test}/**/*.{js,gjs,ts,gts,mts,cts}' --check --no-error-on-unmatched-pattern\",\n \"lint:prettier:fix\": \"pnpm prettier '{javascripts,desktop,mobile,common,scss,stylesheets}/**/*.scss' '{javascripts,test}/**/*.{js,gjs,ts,gts,mts,cts}' -w --no-error-on-unmatched-pattern\",\n \"lint:types\": \"ember-tsc -b\",\n \"lttf:ignore\": \"lint-to-the-future ignore\",\n \"update-skeleton\": \"pnpx @discourse/update-skeleton@latest\"\n },\n \"engines\": {\n \"node\": \">= 22\",\n \"npm\": \"please-use-pnpm\",\n \"yarn\": \"please-use-pnpm\",\n \"pnpm\": \"^10\"\n },\n \"packageManager\": \"pnpm@10.28.0\"\n}\n", ".gitignore": "node_modules\n.discourse-site\n.eslintcache\n", "eslint.config.mjs": "import DiscourseRecommendedTheme from \"@discourse/lint-configs/eslint-theme\";\n\nexport default [...DiscourseRecommendedTheme];\n", ".prettierrc.cjs": "module.exports = require(\"@discourse/lint-configs/prettier\");\n", diff --git a/test/update.test.js b/test/update.test.js index eb1936a..491ae8e 100644 --- a/test/update.test.js +++ b/test/update.test.js @@ -80,13 +80,13 @@ for (const type of ["theme", "plugin"]) { assert.equal(pkg.private, false); assert.equal(pkg.scripts.build, "custom build"); assert.equal( - pkg.scripts["discourse-skeleton-update"], - "pnpx discourse-skeleton-update@latest" + pkg.scripts["update-skeleton"], + "pnpx @discourse/update-skeleton@latest" ); assert.equal(pkg.optionalDependencies.eslint, "10.6.0"); assert.equal(pkg.devDependencies.eslint, undefined); assert.equal(pkg.devDependencies["ember-template-lint"], undefined); - assert.equal(pkg.devDependencies["discourse-skeleton-update"], undefined); + assert.equal(pkg.devDependencies["@discourse/update-skeleton"], undefined); assert.equal( await fs.readFile(path.join(f.directory, "eslint.config.mjs"), "utf8"), f.snapshot.files["eslint.config.mjs"] @@ -158,8 +158,7 @@ test("a failed Bundler update stops subsequent commands and can be retried", asy }); test("CLI help works without a project and unknown options fail", async () => { - const cli = new URL("../bin/discourse-skeleton-update.js", import.meta.url) - .pathname; + const cli = new URL("../bin/update-skeleton.js", import.meta.url).pathname; const { stdout } = await execa(process.execPath, [cli, "--help"]); assert.match(stdout, /theme or plugin root/); await assert.rejects(