Skip to content

add deprecation script#14631

Open
emily-shen wants to merge 2 commits into
mainfrom
emily/deprecation-script
Open

add deprecation script#14631
emily-shen wants to merge 2 commits into
mainfrom
emily/deprecation-script

Conversation

@emily-shen

@emily-shen emily-shen commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

mini cli to deprecate multiple packages in lock step.

Examples:

  pnpm deprecate-packages --reason "Deploy regression" \
    wrangler@latest \
    @cloudflare/vite-plugin@latest \
    @cloudflare/vitest-pool-workers@latest

  pnpm deprecate-packages --reason "Broken scheduled handlers" \
    miniflare@4.20260706.0 \
    wrangler@4.108.0>4.106.0 \
    @cloudflare/vite-plugin@1.43.2 \
    @cloudflare/vitest-pool-workers@0.18.2

Dependency rules (enforced automatically):
miniflare -> must also deprecate wrangler, vite-plugin, vitest-pool-workers
wrangler -> must also deprecate vite-plugin, vitest-pool-workers

  1. runs npm login, opening up the browser for the user to auth to our publisher account
  2. validates that we're deprecating all dependencies (ie if deprecating wrangler, vite and vitest must be included)
  3. resolves tags (e.g. 'latest'), finds the last 'good' version if not provided
  4. prints commands it is going to run - npm dist-tag add <package>@<good-version> latest on the good version, npm deprecate <package>@<bad-version> <reason>
  5. asks for user confirmation
  6. executes commands

you can also test this manually with --dry-run


  • Tests
    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows:
    • Additional testing not necessary because:
  • Public documentation
    • Cloudflare docs PR(s):
    • Documentation not necessary because: internal tool

A picture of a cute animal (not mandatory, but encouraged)

@changeset-bot

changeset-bot Bot commented Jul 9, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 3d3ace3

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

ask-bonk[bot]

This comment was marked as resolved.

@ask-bonk

ask-bonk Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review posted successfully to PR #14631 with a summary and 3 ranked issues (2 as inline suggestion comments):

  1. (High) dist-tag add ... latest runs unconditionally — can downgrade the latest tag when deprecating an older non-latest version.
  2. (Medium) Rollback target chosen by publish time rather than semver — risks selecting a backported patch or prerelease across a major version.
  3. (Medium) User-supplied reason interpolated into a shell command string run via execSync — breaks on quotes and permits injection (CWE-78).

github run

@pkg-pr-new

pkg-pr-new Bot commented Jul 9, 2026

Copy link
Copy Markdown
@cloudflare/autoconfig

npm i https://pkg.pr.new/@cloudflare/autoconfig@14631

create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@14631

@cloudflare/deploy-helpers

npm i https://pkg.pr.new/@cloudflare/deploy-helpers@14631

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@14631

miniflare

npm i https://pkg.pr.new/miniflare@14631

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@14631

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@14631

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@14631

@cloudflare/vitest-pool-workers

npm i https://pkg.pr.new/@cloudflare/vitest-pool-workers@14631

@cloudflare/workers-auth

npm i https://pkg.pr.new/@cloudflare/workers-auth@14631

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@14631

@cloudflare/workers-utils

npm i https://pkg.pr.new/@cloudflare/workers-utils@14631

wrangler

npm i https://pkg.pr.new/wrangler@14631

commit: 3d3ace3

@emily-shen emily-shen added the ci:no-changeset-required Skip pull request checks for a valid changeset label Jul 10, 2026
@emily-shen emily-shen force-pushed the emily/deprecation-script branch from 2d3f40c to fa50094 Compare July 10, 2026 12:26
@emily-shen emily-shen marked this pull request as ready for review July 10, 2026 12:26
@workers-devprod workers-devprod requested review from a team and ascorbic and removed request for a team July 10, 2026 12:27
@workers-devprod

Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • package.json: [@cloudflare/wrangler]
  • tools/deployments/tests/deprecate.test.ts: [@cloudflare/wrangler]
  • tools/deployments/deprecate.ts: [@cloudflare/wrangler]

devin-ai-integration[bot]

This comment was marked as resolved.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

Open in Devin Review

Comment on lines +99 to +110
for (const name of packageNames) {
if (!(name in graph)) {
throw new Error(
`"${name}" is not a known package. Known packages:\n ${knownPackages.join(", ")}`
);
}
for (const dep of graph[name]) {
if (!provided.has(dep) && !missing.includes(dep)) {
missing.push(dep);
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Dependency check reports incomplete list of required packages, forcing users to re-run multiple times

The missing-dependants check (getRequiredDependants at tools/deployments/deprecate.ts:99-110) only iterates over the user-provided package names, not the discovered missing ones, so transitive dependants are never reported in a single pass.

Impact: Users deprecating a low-level package may need to re-run the tool multiple times before all required co-deprecations are surfaced.

Transitive closure is not computed — only direct dependants of provided packages are checked

The function iterates for (const name of packageNames) and collects dependants of each, but never recurses into the collected missing list. In the real repo graph:

  • @cloudflare/kv-asset-handler has dependant wrangler
  • wrangler has dependants @cloudflare/vite-plugin, @cloudflare/vitest-pool-workers

When a user runs deprecate-packages @cloudflare/kv-asset-handler@latest, the function only reports wrangler as missing. After the user adds wrangler and re-runs, it then reports @cloudflare/vite-plugin and @cloudflare/vitest-pool-workers. The error message at tools/deployments/deprecate.ts:408 says "Re-run with versions for all affected packages" but doesn't provide the complete list.

Similarly for @cloudflare/unenv-presetwrangler@cloudflare/vitest-pool-workers.

A fix would be to iterate until a fixed point (or use a queue/BFS), adding newly-discovered missing dependants to the iteration set.

Prompt for agents
The getRequiredDependants function in tools/deployments/deprecate.ts:91-113 only checks direct dependants of the user-provided packageNames, but does not compute the transitive closure. This means if A depends on B depends on C, and the user only provides A, the function reports B as missing but not C.

To fix this, change the iteration to use a queue/worklist approach: start with the user-provided packageNames, and for each missing dependant discovered, also check ITS dependants. Continue until no new missing dependants are found. A simple approach is to use a while loop with a queue:

1. Initialize a queue with all packageNames
2. Pop from queue, check dependants in graph[name]
3. If a dependant is not in provided set and not already in missing set, add to missing and also add to queue
4. Continue until queue is empty

This ensures all transitive dependants are reported in a single invocation. The existing tests would still pass since the TEST_GRAPH happens to have all transitive dependants also as direct dependants of miniflare, but a new test case should be added for a true transitive chain (e.g., A -> B -> C where C is not a direct dependant of A).
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@emily-shen emily-shen Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think this is worth the effort - its highly unlikely we're going to deprecate these packages

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:no-changeset-required Skip pull request checks for a valid changeset

Projects

Status: Untriaged

Development

Successfully merging this pull request may close these issues.

2 participants