@grafana/create-plugin 7.16.0 → 7.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/codemods/additions/additions.js +7 -0
  3. package/dist/codemods/additions/prompts/rspack.md +118 -0
  4. package/dist/codemods/additions/scripts/docs.js +2 -2
  5. package/dist/codemods/additions/scripts/rspack.js +322 -0
  6. package/dist/codemods/agentic/prompts.js +1 -1
  7. package/dist/codemods/migrations/migrations.js +13 -1
  8. package/dist/codemods/migrations/scripts/019-remove-glob-dependency.js +93 -0
  9. package/dist/codemods/migrations/scripts/020-rename-rspack-feature-flag.js +8 -0
  10. package/dist/codemods/utils.ast.js +44 -1
  11. package/dist/codemods/utils.rspack.js +38 -0
  12. package/dist/commands/generate.command.js +1 -9
  13. package/dist/constants.js +0 -1
  14. package/dist/utils/utils.templates.js +4 -4
  15. package/package.json +1 -1
  16. package/src/codemods/additions/additions.test.ts +9 -0
  17. package/src/codemods/additions/additions.ts +7 -0
  18. package/src/codemods/additions/prompts/rspack.md +118 -0
  19. package/src/codemods/additions/scripts/docs.test.ts +4 -4
  20. package/src/codemods/additions/scripts/docs.ts +2 -2
  21. package/src/codemods/additions/scripts/rspack.test.ts +768 -0
  22. package/src/codemods/additions/scripts/rspack.ts +428 -0
  23. package/src/codemods/agentic/prompts.test.ts +11 -2
  24. package/src/codemods/agentic/prompts.ts +1 -1
  25. package/src/codemods/migrations/migrations.ts +14 -1
  26. package/src/codemods/migrations/scripts/019-remove-glob-dependency.test.ts +146 -0
  27. package/src/codemods/migrations/scripts/019-remove-glob-dependency.ts +121 -0
  28. package/src/codemods/migrations/scripts/020-rename-rspack-feature-flag.test.ts +94 -0
  29. package/src/codemods/migrations/scripts/020-rename-rspack-feature-flag.ts +8 -0
  30. package/src/codemods/utils.ast.test.ts +151 -0
  31. package/src/codemods/utils.ast.ts +60 -0
  32. package/src/codemods/utils.rspack.ts +58 -0
  33. package/src/codemods/utils.test.ts +5 -2
  34. package/src/commands/generate.command.ts +2 -10
  35. package/src/constants.ts +0 -1
  36. package/src/types.ts +1 -1
  37. package/src/utils/tests/utils.config.test.ts +10 -0
  38. package/src/utils/utils.config.ts +2 -1
  39. package/src/utils/utils.templates.ts +4 -4
  40. package/templates/common/.config/AGENTS/instructions.md +2 -2
  41. package/templates/common/.config/README.md +56 -0
  42. package/templates/common/.config/bundler/externals.ts +2 -2
  43. package/templates/common/.config/bundler/utils.ts +10 -9
  44. package/templates/common/.config/rspack/DiagnosticsRspackPlugin.ts +29 -0
  45. package/templates/common/.config/rspack/LicenseRspackPlugin.ts +43 -0
  46. package/templates/common/.config/rspack/LiveReloadRspackPlugin.ts +95 -0
  47. package/templates/common/.config/rspack/rspack.config.ts +41 -32
  48. package/templates/common/.cprc.json +1 -2
  49. package/templates/common/_package.json +19 -20
  50. package/templates/common/.config/rspack/liveReloadPlugin.ts +0 -133
@@ -34,6 +34,33 @@ function findVariableDeclaration(ast, variableName) {
34
34
  });
35
35
  return found;
36
36
  }
37
+ function findFunctionDeclaration(ast, functionName) {
38
+ let found = null;
39
+ recast.types.visit(ast, {
40
+ visitFunctionDeclaration(path) {
41
+ if (path.node.id?.name === functionName) {
42
+ found = path.node;
43
+ return false;
44
+ }
45
+ return this.traverse(path);
46
+ }
47
+ });
48
+ return found;
49
+ }
50
+ function callsFunction(ast, functionName) {
51
+ let isCalled = false;
52
+ recast.types.visit(ast, {
53
+ visitCallExpression(path) {
54
+ const { callee } = path.node;
55
+ if (callee.type === "Identifier" && callee.name === functionName) {
56
+ isCalled = true;
57
+ return false;
58
+ }
59
+ return this.traverse(path);
60
+ }
61
+ });
62
+ return isCalled;
63
+ }
37
64
  function isProperty(node) {
38
65
  return node.type === "Property" || node.type === "ObjectProperty";
39
66
  }
@@ -71,5 +98,21 @@ function insertImports(ast, imports) {
71
98
  ast.program.body.unshift(...imports);
72
99
  }
73
100
  }
101
+ function findImports(ast, packageName) {
102
+ return ast.program.body.filter(
103
+ (node) => node.type === "ImportDeclaration" && node.source.value === packageName
104
+ );
105
+ }
106
+ function findNamedImport(ast, packageName, importedName) {
107
+ for (const declaration of findImports(ast, packageName)) {
108
+ const specifier = declaration.specifiers?.find(
109
+ (candidate) => candidate.type === "ImportSpecifier" && candidate.imported.name === importedName
110
+ );
111
+ if (specifier) {
112
+ return { declaration, specifier };
113
+ }
114
+ }
115
+ return void 0;
116
+ }
74
117
 
75
- export { createImport, findObjectProperty, findVariableDeclaration, insertImports, isProperty, parseAsTypescript, printAST };
118
+ export { callsFunction, createImport, findFunctionDeclaration, findImports, findNamedImport, findObjectProperty, findVariableDeclaration, insertImports, isProperty, parseAsTypescript, printAST };
@@ -0,0 +1,38 @@
1
+ import { readJsonFile } from './utils.js';
2
+
3
+ const ROOT_CPRC_PATH = ".config/.cprc.json";
4
+ const USER_CPRC_PATH = ".cprc.json";
5
+ const EXPERIMENTAL_RSPACK_FLAG = "useExperimentalRspack";
6
+ function replaceExperimentalRspackFlag(context, { enable }) {
7
+ const wasRspack = [ROOT_CPRC_PATH, USER_CPRC_PATH].some(
8
+ (path) => readCprc(context, path)?.features?.[EXPERIMENTAL_RSPACK_FLAG] === true
9
+ );
10
+ updateFeatures(context, USER_CPRC_PATH, (features) => withoutExperimentalFlag(features));
11
+ updateFeatures(context, ROOT_CPRC_PATH, (features) => {
12
+ const cleaned = withoutExperimentalFlag(features);
13
+ return enable || wasRspack ? { ...cleaned, useRspack: true } : cleaned;
14
+ });
15
+ }
16
+ function readCprc(context, path) {
17
+ if (!context.doesFileExist(path)) {
18
+ return void 0;
19
+ }
20
+ return readJsonFile(context, path);
21
+ }
22
+ function updateFeatures(context, path, update) {
23
+ const config = readCprc(context, path);
24
+ if (!config) {
25
+ return;
26
+ }
27
+ const features = config.features ?? {};
28
+ const updatedFeatures = update(features);
29
+ if (JSON.stringify(updatedFeatures) === JSON.stringify(features)) {
30
+ return;
31
+ }
32
+ context.updateFile(path, JSON.stringify({ ...config, features: updatedFeatures }, null, 2));
33
+ }
34
+ function withoutExperimentalFlag(features) {
35
+ return Object.fromEntries(Object.entries(features).filter(([name]) => name !== EXPERIMENTAL_RSPACK_FLAG));
36
+ }
37
+
38
+ export { replaceExperimentalRspackFlag };
@@ -96,15 +96,7 @@ function getActionsForTemplateFolder({
96
96
  if (templateData.packageManagerName === "yarn") {
97
97
  files = files.filter((file) => path.basename(file) !== "npmrc");
98
98
  }
99
- files = files.filter((file) => {
100
- if (file.includes("webpack") && templateData.useExperimentalRspack) {
101
- return false;
102
- }
103
- if (file.includes("rspack") && !templateData.useExperimentalRspack) {
104
- return false;
105
- }
106
- return true;
107
- });
99
+ files = files.filter((file) => !file.includes("rspack"));
108
100
  function getFileExportPath(f) {
109
101
  return path.relative(folderPath, path.dirname(f));
110
102
  }
package/dist/constants.js CHANGED
@@ -32,7 +32,6 @@ const EXTRA_TEMPLATE_VARIABLES = {
32
32
  };
33
33
  const DEFAULT_FEATURE_FLAGS = {
34
34
  bundleGrafanaUI: false,
35
- useExperimentalRspack: false,
36
35
  useExperimentalUpdates: true
37
36
  };
38
37
  const GRAFANA_FE_PACKAGES = ["@grafana/data", "@grafana/runtime", "@grafana/schema", "@grafana/ui"];
@@ -75,8 +75,8 @@ function buildTemplateData({
75
75
  bundleGrafanaUI: features.bundleGrafanaUI ?? DEFAULT_FEATURE_FLAGS.bundleGrafanaUI,
76
76
  scenesVersion: "^8.17.0",
77
77
  pluginExecutable: pluginJson.executable,
78
- useExperimentalRspack: Boolean(features.useExperimentalRspack),
79
- frontendBundler: features.useExperimentalRspack ? "rspack" : "webpack"
78
+ useRspack: Boolean(features.useRspack),
79
+ frontendBundler: features.useRspack ? "rspack" : "webpack"
80
80
  };
81
81
  }
82
82
  function isAppType(pluginType) {
@@ -89,7 +89,7 @@ function getTemplateData(cliArgs) {
89
89
  const { features } = getConfig();
90
90
  const currentVersion = CURRENT_APP_VERSION;
91
91
  const bundleGrafanaUI = features.bundleGrafanaUI ?? DEFAULT_FEATURE_FLAGS.bundleGrafanaUI;
92
- const frontendBundler = features.useExperimentalRspack ? "rspack" : "webpack";
92
+ const frontendBundler = features.useRspack ? "rspack" : "webpack";
93
93
  let templateData;
94
94
  if (cliArgs) {
95
95
  const { packageManagerName, packageManagerVersion } = getPackageManagerFromUserAgent();
@@ -109,7 +109,7 @@ function getTemplateData(cliArgs) {
109
109
  version: currentVersion,
110
110
  bundleGrafanaUI,
111
111
  scenesVersion: "^8.17.0",
112
- useExperimentalRspack: Boolean(features.useExperimentalRspack),
112
+ useRspack: Boolean(features.useRspack),
113
113
  frontendBundler
114
114
  };
115
115
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grafana/create-plugin",
3
- "version": "7.16.0",
3
+ "version": "7.18.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "directory": "packages/create-plugin",
@@ -56,6 +56,15 @@ describe('additions json', () => {
56
56
  expect(defaultAdditions.length).toBeGreaterThan(0);
57
57
  });
58
58
 
59
+ it('should register rspack as a hybrid addition', () => {
60
+ const rspack = defaultAdditions.find((addition) => addition.name === 'rspack');
61
+
62
+ expect(rspack).toBeDefined();
63
+ expect(isScriptAddition(rspack!)).toBe(true);
64
+ expect(hasPromptStep(rspack!)).toBe(true);
65
+ expect(rspack!.verify).toEqual(['typecheck', 'build']);
66
+ });
67
+
59
68
  defaultAdditions.forEach((addition) => {
60
69
  it(`should declare a script path or a prompt for ${addition.name}`, () => {
61
70
  expect(isScriptAddition(addition) || hasPromptStep(addition)).toBe(true);
@@ -39,6 +39,13 @@ const additions: Addition[] = [
39
39
  description: 'Externalizes the react JSX runtime to help migrate plugins to React 19',
40
40
  scriptPath: import.meta.resolve('./scripts/externalize-jsx-runtime.js'),
41
41
  },
42
+ {
43
+ name: 'rspack',
44
+ description: 'Migrates the plugin frontend build from webpack or experimental rspack to rspack 2',
45
+ scriptPath: import.meta.resolve('./scripts/rspack.js'),
46
+ prompt: import.meta.resolve('./prompts/rspack.md'),
47
+ verify: ['typecheck', 'build'],
48
+ },
42
49
  {
43
50
  name: 'experimental-app-sdk',
44
51
  description: 'Adds grafana-app-sdk CUE kind code generation to an app plugin',
@@ -0,0 +1,118 @@
1
+ # Migrate the plugin's custom build configuration to rspack
2
+
3
+ ## Context
4
+
5
+ This plugin is moving its frontend build to rspack 2. The `create-plugin add rspack` codemod has already done the parts that create-plugin owns:
6
+
7
+ - Rendered the rspack base config in `.config/rspack/` and the shared helpers in `.config/bundler/`, and set `useRspack` in `.config/.cprc.json`.
8
+ - Deleted the create-plugin files in `.config/webpack/`. It kept any file there that the plugin added and listed it in its output.
9
+ - Added the rspack packages (`@rspack/core`, `@rspack/cli`, `rspack-merge`, `diagnostics-webpack-plugin` and others) and removed webpack-only packages. It kept any webpack package that a root `webpack.*` or `rspack.*` file still imports and listed it.
10
+ - Rewrote `webpack` commands in `package.json` scripts to `rspack`. It listed any script it could not rewrite.
11
+ - If the plugin has a root `webpack.config.*`, added a root `rspack.config.ts` that throws an `[rspack]` error until the custom config is ported.
12
+ - Raised `engines.node` to `>=22.23` if it allowed older versions.
13
+
14
+ What is left is the plugin's own build customisation, which needs judgement to port. The previous base config is still in git: `git show HEAD:.config/webpack/webpack.config.ts`. Compare it with `.config/rspack/rspack.config.ts` when you need to know how a base rule or plugin changed.
15
+
16
+ ## Check first
17
+
18
+ 1. Install dependencies with the plugin's package manager, then run the `build` script. Keep the output; it is evidence, not a to-do list.
19
+ 2. Stop and report that nothing was needed if all of these are true:
20
+ - The build passes.
21
+ - There is no root `webpack.config.*` file.
22
+ - Root `rspack.config.ts`, if present, does not contain the `[rspack]` error.
23
+ - No script in `package.json` calls `webpack`.
24
+ - No plugin code builds a runtime URL to a file the new base config no longer copies into `dist` (see step 6).
25
+ 3. Otherwise, work out the starting point:
26
+ - **From webpack**: there is a root `webpack.config.*`, or `rspack.config.ts` contains the `[rspack]` error. Follow all the steps below.
27
+ - **From experimental rspack**: there is a root `rspack.config.ts` without the `[rspack]` error, and there is no root `webpack.config.*`. The config is already rspack but may use rspack 1 APIs. Skip step 2 and upgrade that file in place using steps 3 to 7.
28
+ - **No custom config**: there is neither a root `webpack.config.*` nor a root `rspack.config.ts`. Only step 6 applies.
29
+
30
+ With a custom config, the build is expected to fail at this point with the `[rspack]` error. Do not chase build errors one by one; the steps below drive the work.
31
+
32
+ ## Steps
33
+
34
+ 1. Find every file that is part of the custom build: the root `webpack.config.*`, any file it imports (for example `webpack.config.utils.ts`), and any file the codemod reported as kept in `.config/webpack/`.
35
+
36
+ 2. Replace the body of root `rspack.config.ts` with a port of the root webpack config:
37
+ - Import the base config with `import grafanaConfig, { type Env } from './.config/rspack/rspack.config.ts';`.
38
+ - Merge with `rspack-merge` (`merge`, `mergeWithRules`, `mergeWithCustomize`, `unique`). It has the same API as `webpack-merge`, typed for rspack. Await the base config before merging.
39
+ - Keep the structure, comments and behaviour of the original. Port it; do not improve it.
40
+ - Remove the `[rspack]` error and the `TODO(rspack)` comment above it only when the port is complete.
41
+
42
+ 3. Replace webpack APIs and packages with their rspack equivalents. Import from `@rspack/core` with named imports, for example `import { DefinePlugin, NormalModuleReplacementPlugin } from '@rspack/core';`.
43
+
44
+ | webpack | rspack |
45
+ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
46
+ | `webpack` built-in plugins (`DefinePlugin`, `EnvironmentPlugin`, `BannerPlugin`, `ProvidePlugin`, `NormalModuleReplacementPlugin`, `ContextReplacementPlugin`) and `Compilation` | the same names from `@rspack/core` |
47
+ | `webpack-merge` | `rspack-merge` |
48
+ | `copy-webpack-plugin` | `CopyRspackPlugin` from `@rspack/core` |
49
+ | `swc-loader`, `babel-loader` | `builtin:swc-loader` |
50
+ | `fork-ts-checker-webpack-plugin` | `TsCheckerRspackPlugin` from `ts-checker-rspack-plugin` |
51
+ | `eslint-webpack-plugin`, `eslint-rspack-plugin`, or `diagnostics-webpack-plugin` used directly | `DiagnosticsRspackPlugin` from `./.config/rspack/DiagnosticsRspackPlugin.ts`, with `checks: [{ use: 'eslint', ... }]`. It wraps `diagnostics-webpack-plugin`, which fails under rspack on its own. `failOnError` and `severity` become `reportAs` |
52
+ | `webpack-livereload-plugin` | already in the base config for development builds |
53
+ | `mini-css-extract-plugin` | `CssExtractRspackPlugin` from `@rspack/core` |
54
+ | `css-minimizer-webpack-plugin` | `LightningCssMinimizerRspackPlugin` from `@rspack/core` |
55
+ | `terser-webpack-plugin` added by the plugin | `SwcJsMinimizerRspackPlugin` from `@rspack/core`, or keep terser |
56
+ | `html-webpack-plugin` | `HtmlRspackPlugin` from `@rspack/core` |
57
+ | `tsconfig-paths-webpack-plugin` | the `resolve.tsConfig` option |
58
+ | `file-loader`, `url-loader`, `raw-loader` | asset modules: `type: 'asset/resource'`, `'asset/inline'`, `'asset/source'` |
59
+ | plugins built on unplugin (`x/webpack`) | the `x/rspack` entry point, where one exists |
60
+ | imports from `.config/webpack/utils` or `.config/webpack/constants` | `.config/bundler/utils.ts` and `.config/bundler/constants.ts` |
61
+
62
+ Check the [rspack migration guide](https://rspack.rs/guide/migration/webpack) for anything not listed here.
63
+
64
+ 4. Fix code that depends on how the base config is built. Each of these works in webpack and silently does nothing, or throws, in rspack:
65
+ - **Looking up a rule by loader name**, such as `rule.use.loader === 'swc-loader'`. The base config uses `builtin:swc-loader`, so match that. Prefer merging a rule over mutating the base one.
66
+ - **Looking up a plugin with `instanceof` or `constructor.name`** against webpack plugin classes, such as `CopyWebpackPlugin` or `LiveReloadPlugin`. Use the rspack class names, or merge instead of mutating.
67
+ - **`webpack-merge` rules keyed on old names**: `unique('plugins', ['CopyPlugin'], …)` or `mergeWithRules` matching `use.loader: 'swc-loader'`. Update the names.
68
+ - **A `filter` function on a `CopyWebpackPlugin` pattern**. `CopyRspackPlugin` has no `filter`; use `globOptions: { ignore: [...] }`. The base copy patterns come from `.config/bundler/copyFiles.ts`.
69
+ - **Removing the live reload plugin by filtering the plugins array**. The rspack base only adds it in development; filter on the rspack plugin class.
70
+ - **Native ESM loading**: the rspack CLI loads `rspack.config.ts` as native ESM. Replace `__dirname` with `import.meta.dirname`, `require.resolve(x)` with `createRequire(import.meta.url).resolve(x)`, and `require(x)` with `import`. Give relative imports explicit `.ts` extensions. `ReferenceError: __dirname is not defined` at build time means this step is not done.
71
+ - **rspack 2 defaults**: imports of exports that do not exist now fail the build (`exportsPresence: 'error'`). Fix the import in the plugin's code if it is clearly wrong; otherwise report it rather than changing the setting.
72
+ - **rspack 2 option moves**: `experiments.cache`, `experiments.incremental` and `experiments.lazyCompilation` are now top level. `experiments.css` is replaced by `module.rules[].type: 'css' | 'css/module' | 'css/auto'`. `experiments.outputModule` is `output.module`. `output.libraryTarget`, `libraryExport` and `umdNamedDefine` move under `output.library`. `SubresourceIntegrityPlugin` is no longer under `experiments`.
73
+ - **Persistent cache**: the base config has none. If the webpack config set `cache.type: 'filesystem'`, drop it unless the plugin clearly needs it.
74
+
75
+ 5. Check whether the config adds a second transpiler for the plugin's own code. A rule that runs `esbuild-loader`, `babel-loader` or `ts-loader` on `.ts`, `.tsx`, `.js` or `.jsx` files outside `node_modules` overlaps with the base `builtin:swc-loader` rule. Every matching rule applies, so each file is transpiled twice, and the build still passes, so nothing flags it.
76
+ - Do not port the extra rule as it is.
77
+ - If the base `builtin:swc-loader` settings cover what the rule did, leave the rule out of `rspack.config.ts` and remove its loader package once nothing else uses it.
78
+ - If the rule does something the base config does not, for example a different JSX runtime or decorator support, move that setting into the `builtin:swc-loader` rule (see step 4) and leave the extra rule out.
79
+ - If you cannot tell, keep the rule with a `TODO(rspack):` comment above it explaining that it duplicates the base transpiler.
80
+ - Either way, name the rule in your report.
81
+
82
+ 6. Check for files the old base config copied into `dist` that the new one does not. The old base copied every `img/**`, `**/*.svg`, `**/*.png`, `**/*.html`, `libs/**` and `static/**` file; compare `git show HEAD:.config/webpack/webpack.config.ts` with `.config/bundler/copyFiles.ts`. The new base copies only `plugin.json` and other JSON files, the README, CHANGELOG and LICENSE, `query_help.md`, and the logos and screenshots listed in `plugin.json`. Code that builds a URL to one of the other files at runtime, for example `public/plugins/<plugin-id>/img/…` or `` `${pluginPublicPath}/img/how-it-works.svg` ``, now gets a 404. The build still passes, so nothing flags it.
83
+ - Where the path is a literal, import the file and use the imported URL, for example `import howItWorks from '../img/how-it-works.svg';` and `src={howItWorks}`. rspack then hashes the file and resolves its public path, including when the plugin is served from a CDN.
84
+ - Check what an import returns before converting. If the config sends `.svg` imports to `@svgr/webpack` or another loader, the import is a React component, not a URL. Use that loader's URL form if it has one, such as a `?url` resource query, or copy the file instead.
85
+ - The base asset rules only cover `png`, `jpg`, `jpeg`, `gif`, `svg` and font files. For other types, such as `webp`, add an `asset/resource` rule in `rspack.config.ts`.
86
+ - Copy the file instead of importing it when the path is built at runtime, for example `` `${base}/img/${name}.svg` ``, or when something outside the bundle refers to it, such as the README, documentation or another plugin. Add a `CopyRspackPlugin` to `rspack.config.ts` for just those files, with a comment saying why they are copied. Do not copy whole folders to be safe: every copied file ends up in the plugin archive.
87
+
88
+ 7. If something has no rspack equivalent, for example a monkey-patch of webpack internals, a custom `RuntimeModule` plugin, or an SWC Wasm plugin whose ABI does not match rspack's built-in SWC:
89
+ - Port what you can.
90
+ - Comment out the rest, keeping the original code in the comment, so it does not run and the build does not fail.
91
+ - Put a `TODO(rspack):` comment above it that says what the code did, why it has no direct equivalent, and a suggested approach.
92
+ - Never drop it silently.
93
+
94
+ 8. Fix any script the codemod reported as not rewritten so it calls `rspack` with `./rspack.config.ts` or `./.config/rspack/rspack.config.ts`, keeping its other commands and flags. Remove the CLI flags rspack does not support: `--progress`, `--color`, `--bail`, `--output-pathinfo`.
95
+
96
+ 9. For each file the codemod kept in `.config/webpack/`, copy what is still needed to a folder outside `.config/` (for example `build/`), port it to rspack, and update the imports. Do not delete the originals; list them so the user can delete them.
97
+
98
+ 10. Remove the webpack packages the codemod kept, once nothing imports them. Keep `webpack` itself if anything still imports it.
99
+
100
+ 11. Delete the root `webpack.config.*` and its helper files once everything in them is ported or commented with `TODO(rspack):`.
101
+
102
+ ## Verify
103
+
104
+ 1. Install dependencies, then run the `typecheck` and `build` scripts. Both must pass, with any unportable code commented out.
105
+ 2. Check that `dist/` contains `module.js`, `plugin.json`, and every file that plugin code or `plugin.json` refers to by path at runtime. Imported images are hashed, so their names change.
106
+ 3. Run the `dev` script briefly and check that it compiles and keeps watching.
107
+ 4. Fix only breakage caused by this migration.
108
+
109
+ ## Report
110
+
111
+ End with a list of every `TODO(rspack):` comment you added (file, line, one-line reason), every file the user should delete, any duplicate transpiler rule you removed or kept (step 5), every image reference you changed to an import or kept as a copy (step 6), and any `exportsPresence` errors you left for the user.
112
+
113
+ ## Out of scope
114
+
115
+ - Do not modify anything under `.config/`. It is managed by create-plugin and is overwritten by `create-plugin update`.
116
+ - Do not change the plugin id or type in `src/plugin.json`.
117
+ - Do not upgrade unrelated dependencies, and do not reformat files you did not change.
118
+ - Do not refactor plugin source code, unless the build fails because of the bundler change or step 6 needs an image import.
@@ -225,7 +225,7 @@ describe('docs scaffolding', () => {
225
225
  const context = makeContext();
226
226
  call(context);
227
227
  const pkg = JSON.parse(context.getFile('package.json') ?? '{}');
228
- expect(pkg.devDependencies?.['@grafana/plugin-docs-cli']).toBe('^0.8.0');
228
+ expect(pkg.devDependencies?.['@grafana/plugin-docs-cli']).toBe('^0.13.0');
229
229
  });
230
230
 
231
231
  it('adds docs:serve and docs:validate scripts, with no separate release script', () => {
@@ -358,9 +358,9 @@ describe('docs scaffolding', () => {
358
358
  );
359
359
  });
360
360
 
361
- it('raises package-plugin to package-plugin/v1.3.3', () => {
361
+ it('raises package-plugin to package-plugin/v1.3.6', () => {
362
362
  expect(bumped('uses: grafana/plugin-actions/package-plugin@package-plugin/v1.3.2\n')).toBe(
363
- 'uses: grafana/plugin-actions/package-plugin@package-plugin/v1.3.3\n'
363
+ 'uses: grafana/plugin-actions/package-plugin@package-plugin/v1.3.6\n'
364
364
  );
365
365
  });
366
366
 
@@ -1851,7 +1851,7 @@ describe('docs codemod', () => {
1851
1851
  'uses: grafana/plugin-actions/package-plugin@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n'
1852
1852
  );
1853
1853
  const body = nextSteps(context).join('\n');
1854
- expect(body).toContain('Docs need package-plugin/v1.3.3 or later.');
1854
+ expect(body).toContain('Docs need package-plugin/v1.3.6 or later.');
1855
1855
  expect(body).not.toContain('Make sure your release pipeline');
1856
1856
  });
1857
1857
 
@@ -56,7 +56,7 @@ export const schema = v.object({
56
56
  type Options = v.InferOutput<typeof schema>;
57
57
 
58
58
  // kept current by a Renovate custom manager in .github/renovate.json, which matches this exact line
59
- const PLUGIN_DOCS_CLI_VERSION = '^0.8.0';
59
+ const PLUGIN_DOCS_CLI_VERSION = '^0.13.0';
60
60
 
61
61
  // each type needs a template set under `templates/docs/<type>/`
62
62
  const SUPPORTED_PLUGIN_TYPES = ['panel', 'datasource', 'app'] as const;
@@ -709,7 +709,7 @@ const RELEASE_WORKFLOW_PATH = '.github/workflows/release.yml';
709
709
  // the oldest release of each action that builds docs into the plugin archive
710
710
  const REQUIRED_ACTION_REFS: Record<string, string> = {
711
711
  'grafana/plugin-actions/build-plugin': 'build-plugin/v1.2.0',
712
- 'grafana/plugin-actions/package-plugin': 'package-plugin/v1.3.3',
712
+ 'grafana/plugin-actions/package-plugin': 'package-plugin/v1.3.6',
713
713
  };
714
714
 
715
715
  const DOCS_SCRIPTS: Record<string, string> = {