Skip to content

Commit f58772f

Browse files
authored
Merge pull request #95 from backstage/fix/recipe-aifixup-and-workspace-member
fix: recipe aiFixup forwarding and workspace member skip
2 parents 6d650da + ffc5936 commit f58772f

13 files changed

Lines changed: 113 additions & 0 deletions

File tree

.agents/skills/validate-codemod-recipe/SKILL.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,19 @@ The codemod modifies code it should not touch. Root causes:
103103
- **Name collision**: A field name like `token` or `loading` exists in
104104
unrelated code. Fix: verify the field belongs to the target type before
105105
transforming.
106+
- **Workspace member bleed**: A dependency-adding codemod modifies every
107+
sub-package in a monorepo when the workspace root already provides the
108+
dependency. Use judgement — sometimes sub-packages legitimately need
109+
their own entry (published packages, version pinning). When the codemod
110+
was designed to target only the workspace root (workflow excludes
111+
`packages/**`), add a guard in the transform (e.g., check for a
112+
`workspaces` field). When it makes sense for both root and members,
113+
consider a param like `skipWorkspaceMembers` to let users choose.
114+
- **Workflow glob paths shift with `--target`**: A workflow that excludes
115+
`packages/**/package.json` works with `--target .` but not `--target
116+
packages`, because `include`/`exclude` resolve relative to the target
117+
root. Transforms that should only hit the repo root need guards in the
118+
transform code itself, not just workflow globs.
106119

107120
#### Redundant transforms
108121

@@ -259,3 +272,16 @@ over-restrict the scope.
259272
- **lint-staged interference.** The repo's pre-commit hooks may reformat files
260273
via prettier. If prettier and a generator script (like `yarn readme`)
261274
disagree on formatting, the generator should run prettier as its last step.
275+
- **`params` must be forwarded in recipes.** When a sub-codemod declares
276+
`params:` (e.g., `aiFixup`), the recipe workflow must also declare those
277+
params at its own top level and forward them via `args:` on each step that
278+
uses them. Without this, the codemod CLI crashes with
279+
`Variable identifier is not bound to anything by context: "params.xxx"`.
280+
Compare against v1.50.0+ recipes for the correct pattern.
281+
- **Cross-version audit.** Before fixing one recipe, `grep -r` across all
282+
version directories for the same pattern. A bug in one recipe's
283+
`params`/`args` setup is likely repeated in adjacent versions.
284+
- **JSON test fixtures and `JSON.stringify`.** When a transform round-trips
285+
through `JSON.stringify`, arrays are expanded to one-element-per-line.
286+
Test fixture `input.json` and `expected.json` must match this expanded
287+
format or the test runner reports a false mismatch.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
'@backstage/add-jest-peer-dependency': patch
3+
'@backstage/v1-48-0-migration-recipe': patch
4+
'@backstage/v1-49-0-migration-recipe': patch
5+
---
6+
7+
Fix recipe validation issues found during v1.45–v1.49 testing against the Backstage monorepo:
8+
9+
- **v1.46.0 `add-jest-peer-dependency`**: Skip workspace member packages that inherit jest from the workspace root. Previously the codemod added redundant `jest`, `@types/jest`, `@jest/environment-jsdom-abstract`, and `jsdom` devDependencies to every sub-package even when the workspace root already provides them.
10+
- **v1.48.0 migration recipe**: Add `params.aiFixup` declaration and forward `args: ['aiFixup']` to `migrate-surface-to-bg-system` and `migrate-column-config-to-react-element`. Without this, running the recipe fails with `Variable identifier is not bound to anything by context: "params.aiFixup"`.
11+
- **v1.49.0 migration recipe**: Same `params.aiFixup` fix — add declaration and forward to `remove-create-public-sign-in-app`.

codemods/v1.46.0/add-jest-peer-dependency/scripts/codemod.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ const transform: Codemod<JSON> = async (root, options) => {
6565
return null
6666
}
6767

68+
// Skip workspace member packages — they inherit jest from the workspace root.
69+
// Only the root package.json (which has a "workspaces" field) should be modified.
70+
if (!pkg.workspaces) {
71+
return null
72+
}
73+
6874
// Check if jest is already present
6975
const hasJest = pkg.dependencies?.jest !== undefined || pkg.devDependencies?.jest !== undefined
7076

codemods/v1.46.0/add-jest-peer-dependency/tests/already-has-jest/expected.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
{
22
"name": "my-backstage-app",
3+
"workspaces": {
4+
"packages": [
5+
"packages/*",
6+
"plugins/*"
7+
]
8+
},
39
"devDependencies": {
410
"@backstage/cli": "^0.35.0",
511
"jest": "^29.0.0"

codemods/v1.46.0/add-jest-peer-dependency/tests/already-has-jest/input.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
{
22
"name": "my-backstage-app",
3+
"workspaces": {
4+
"packages": [
5+
"packages/*",
6+
"plugins/*"
7+
]
8+
},
39
"devDependencies": {
410
"@backstage/cli": "^0.35.0",
511
"jest": "^29.0.0"

codemods/v1.46.0/add-jest-peer-dependency/tests/jest30-default/expected.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
{
22
"name": "my-backstage-app",
3+
"workspaces": {
4+
"packages": [
5+
"packages/*",
6+
"plugins/*"
7+
]
8+
},
39
"devDependencies": {
410
"@backstage/cli": "^0.35.0",
511
"@jest/environment-jsdom-abstract": "^30",

codemods/v1.46.0/add-jest-peer-dependency/tests/jest30-default/input.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
{
22
"name": "my-backstage-app",
3+
"workspaces": {
4+
"packages": [
5+
"packages/*",
6+
"plugins/*"
7+
]
8+
},
39
"devDependencies": {
410
"@backstage/cli": "^0.35.0"
511
}

codemods/v1.46.0/add-jest-peer-dependency/tests/jest30-with-existing-deps/expected.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
{
22
"name": "my-backstage-app",
33
"version": "1.0.0",
4+
"workspaces": {
5+
"packages": [
6+
"packages/*",
7+
"plugins/*"
8+
]
9+
},
410
"dependencies": {
511
"@backstage/core-plugin-api": "^1.0.0"
612
},

codemods/v1.46.0/add-jest-peer-dependency/tests/jest30-with-existing-deps/input.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
{
22
"name": "my-backstage-app",
33
"version": "1.0.0",
4+
"workspaces": {
5+
"packages": [
6+
"packages/*",
7+
"plugins/*"
8+
]
9+
},
410
"dependencies": {
511
"@backstage/core-plugin-api": "^1.0.0"
612
},
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "@backstage/plugin-catalog",
3+
"devDependencies": {
4+
"@backstage/cli": "^0.35.0",
5+
"typescript": "^5.0.0"
6+
}
7+
}

0 commit comments

Comments
 (0)