Repository: ember-cli/ember-cli
Pull request #10588 (2024-12-22 15:25:00)

[ENHANCEMENT] Add `ember-cli-deprecation-workflow` to `app` blueprint [RFC 1009]
RFC: https://github.com/emberjs/rfcs/pull/1009

simonihmig: CI seems to be failing with prettier linting failing on the newly added workflow file!

Patch:
diff --git a/blueprints/app/files/app/app.ts b/blueprints/app/files/app/app.ts
index 9efa11633..546873008 100644
--- a/blueprints/app/files/app/app.ts
+++ b/blueprints/app/files/app/app.ts
@@ -2,6 +2,11 @@ import Application from '@ember/application';
 import Resolver from 'ember-resolver';
 import loadInitializers from 'ember-load-initializers';
 import config from '<%= modulePrefix %>/config/environment';
+import { importSync, isDevelopingApp, macroCondition } from '@embroider/macros';
+
+if (macroCondition(isDevelopingApp())) {
+  importSync('./deprecation-workflow');
+}
 
 export default class App extends Application {
   modulePrefix = config.modulePrefix;
diff --git a/blueprints/app/files/app/deprecation-workflow.ts b/blueprints/app/files/app/deprecation-workflow.ts
new file mode 100644
index 000000000..274a689db
--- /dev/null
+++ b/blueprints/app/files/app/deprecation-workflow.ts
@@ -0,0 +1,24 @@
+import setupDeprecationWorkflow from 'ember-cli-deprecation-workflow';
+
+/**
+ * Docs: https://github.com/ember-cli/ember-cli-deprecation-workflow
+ */
+setupDeprecationWorkflow({
+  /**
+    false by default, but if a developer / team wants to be more aggressive about being proactive with
+    handling their deprecations, this should be set to "true"
+  */
+  throwOnUnhandled: false,
+  workflow: [
+    /* ... handlers ... */
+    /* to generate this list, run your app for a while (or run the test suite),
+     * and then run in the browser console:
+     *
+     *    deprecationWorkflow.flushDeprecations()
+     *
+     * And copy the handlers here
+     */
+    /* example: */
+    /* { handler: 'silence', matchId: 'template-action' }, */
+  ],
+});
diff --git a/blueprints/app/files/package.json b/blueprints/app/files/package.json
index f42e0d95f..63bfbe88e 100644
--- a/blueprints/app/files/package.json
+++ b/blueprints/app/files/package.json
@@ -44,7 +44,8 @@
     "@ember/optional-features": "^2.2.0",
     "@ember/test-helpers": "^4.0.4<% if (embroider) { %>",
     "@embroider/compat": "^3.8.0",
-    "@embroider/core": "^3.5.0",
+    "@embroider/core": "^3.5.0<% } %>",
+    "@embroider/macros": "^1.16.10<% if (embroider) { %>",
     "@embroider/webpack": "^4.0.9<% } %>",
     "@eslint/js": "^9.17.0",
     "@glimmer/component": "^2.0.0",
@@ -65,6 +66,7 @@
     "ember-cli-babel": "^8.2.0",
     "ember-cli-clean-css": "^3.0.0",
     "ember-cli-dependency-checker": "^3.3.3",
+    "ember-cli-deprecation-workflow": "^3.1.0",
     "ember-cli-htmlbars": "^6.3.0",
     "ember-cli-inject-live-reload": "^2.1.0<% if (!embroider) { %>",
     "ember-cli-sri": "^2.1.1",
diff --git a/lib/debug/deprecate.js b/lib/debug/deprecate.js
index e6a39cc99..7717b9d60 100644
--- a/lib/debug/deprecate.js
+++ b/lib/debug/deprecate.js
@@ -81,10 +81,6 @@ function deprecate(description, condition, options) {
   let message = formatMessage(description, options);
 
   warn(`${message}\n\n${getStackTrace()}`);
-
-  // Return the message for testing purposes.
-  // This can be removed once we can register deprecation handlers.
-  return message;
 }
 
 function isSemVer(version) {


Test patch:
diff --git a/tests/fixtures/addon/defaults/package.json b/tests/fixtures/addon/defaults/package.json
index 5d3f1c845..7f0ec8219 100644
--- a/tests/fixtures/addon/defaults/package.json
+++ b/tests/fixtures/addon/defaults/package.json
@@ -40,6 +40,7 @@
     "@babel/plugin-proposal-decorators": "^7.25.9",
     "@ember/optional-features": "^2.2.0",
     "@ember/test-helpers": "^4.0.4",
+    "@embroider/macros": "^1.16.10",
     "@embroider/test-setup": "^4.0.0",
     "@eslint/js": "^9.17.0",
     "@glimmer/component": "^2.0.0",
@@ -50,6 +51,7 @@
     "ember-cli": "~<%= emberCLIVersion %>",
     "ember-cli-clean-css": "^3.0.0",
     "ember-cli-dependency-checker": "^3.3.3",
+    "ember-cli-deprecation-workflow": "^3.1.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-cli-sri": "^2.1.1",
     "ember-cli-terser": "^4.0.2",
diff --git a/tests/fixtures/addon/pnpm/package.json b/tests/fixtures/addon/pnpm/package.json
index 4d9f148d1..e154de7a6 100644
--- a/tests/fixtures/addon/pnpm/package.json
+++ b/tests/fixtures/addon/pnpm/package.json
@@ -40,6 +40,7 @@
     "@babel/plugin-proposal-decorators": "^7.25.9",
     "@ember/optional-features": "^2.2.0",
     "@ember/test-helpers": "^4.0.4",
+    "@embroider/macros": "^1.16.10",
     "@embroider/test-setup": "^4.0.0",
     "@eslint/js": "^9.17.0",
     "@glimmer/component": "^2.0.0",
@@ -50,6 +51,7 @@
     "ember-cli": "~<%= emberCLIVersion %>",
     "ember-cli-clean-css": "^3.0.0",
     "ember-cli-dependency-checker": "^3.3.3",
+    "ember-cli-deprecation-workflow": "^3.1.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-cli-sri": "^2.1.1",
     "ember-cli-terser": "^4.0.2",
diff --git a/tests/fixtures/addon/typescript/package.json b/tests/fixtures/addon/typescript/package.json
index ffb2c906a..55d9665f8 100644
--- a/tests/fixtures/addon/typescript/package.json
+++ b/tests/fixtures/addon/typescript/package.json
@@ -56,6 +56,7 @@
   "devDependencies": {
     "@ember/optional-features": "^2.2.0",
     "@ember/test-helpers": "^4.0.4",
+    "@embroider/macros": "^1.16.10",
     "@embroider/test-setup": "^4.0.0",
     "@eslint/js": "^9.17.0",
     "@glimmer/component": "^2.0.0",
@@ -73,6 +74,7 @@
     "ember-cli": "~<%= emberCLIVersion %>",
     "ember-cli-clean-css": "^3.0.0",
     "ember-cli-dependency-checker": "^3.3.3",
+    "ember-cli-deprecation-workflow": "^3.1.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-cli-sri": "^2.1.1",
     "ember-cli-terser": "^4.0.2",
diff --git a/tests/fixtures/addon/yarn/package.json b/tests/fixtures/addon/yarn/package.json
index e8d78b4cc..e48fdd6e8 100644
--- a/tests/fixtures/addon/yarn/package.json
+++ b/tests/fixtures/addon/yarn/package.json
@@ -40,6 +40,7 @@
     "@babel/plugin-proposal-decorators": "^7.25.9",
     "@ember/optional-features": "^2.2.0",
     "@ember/test-helpers": "^4.0.4",
+    "@embroider/macros": "^1.16.10",
     "@embroider/test-setup": "^4.0.0",
     "@eslint/js": "^9.17.0",
     "@glimmer/component": "^2.0.0",
@@ -50,6 +51,7 @@
     "ember-cli": "~<%= emberCLIVersion %>",
     "ember-cli-clean-css": "^3.0.0",
     "ember-cli-dependency-checker": "^3.3.3",
+    "ember-cli-deprecation-workflow": "^3.1.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-cli-sri": "^2.1.1",
     "ember-cli-terser": "^4.0.2",
diff --git a/tests/fixtures/app/defaults/package.json b/tests/fixtures/app/defaults/package.json
index f5846728a..1e9668e8d 100644
--- a/tests/fixtures/app/defaults/package.json
+++ b/tests/fixtures/app/defaults/package.json
@@ -32,6 +32,7 @@
     "@babel/plugin-proposal-decorators": "^7.25.9",
     "@ember/optional-features": "^2.2.0",
     "@ember/test-helpers": "^4.0.4",
+    "@embroider/macros": "^1.16.10",
     "@eslint/js": "^9.17.0",
     "@glimmer/component": "^2.0.0",
     "@glimmer/tracking": "^1.1.2",
@@ -43,6 +44,7 @@
     "ember-cli-babel": "^8.2.0",
     "ember-cli-clean-css": "^3.0.0",
     "ember-cli-dependency-checker": "^3.3.3",
+    "ember-cli-deprecation-workflow": "^3.1.0",
     "ember-cli-htmlbars": "^6.3.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-cli-sri": "^2.1.1",
diff --git a/tests/fixtures/app/embroider-no-welcome/package.json b/tests/fixtures/app/embroider-no-welcome/package.json
index 919d9a580..4f45f94d4 100644
--- a/tests/fixtures/app/embroider-no-welcome/package.json
+++ b/tests/fixtures/app/embroider-no-welcome/package.json
@@ -34,6 +34,7 @@
     "@ember/test-helpers": "^4.0.4",
     "@embroider/compat": "^3.8.0",
     "@embroider/core": "^3.5.0",
+    "@embroider/macros": "^1.16.10",
     "@embroider/webpack": "^4.0.9",
     "@eslint/js": "^9.17.0",
     "@glimmer/component": "^2.0.0",
@@ -46,6 +47,7 @@
     "ember-cli-babel": "^8.2.0",
     "ember-cli-clean-css": "^3.0.0",
     "ember-cli-dependency-checker": "^3.3.3",
+    "ember-cli-deprecation-workflow": "^3.1.0",
     "ember-cli-htmlbars": "^6.3.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-data": "~5.4.0-beta.12",
diff --git a/tests/fixtures/app/embroider-pnpm/package.json b/tests/fixtures/app/embroider-pnpm/package.json
index e689381af..bf01725d1 100644
--- a/tests/fixtures/app/embroider-pnpm/package.json
+++ b/tests/fixtures/app/embroider-pnpm/package.json
@@ -34,6 +34,7 @@
     "@ember/test-helpers": "^4.0.4",
     "@embroider/compat": "^3.8.0",
     "@embroider/core": "^3.5.0",
+    "@embroider/macros": "^1.16.10",
     "@embroider/webpack": "^4.0.9",
     "@eslint/js": "^9.17.0",
     "@glimmer/component": "^2.0.0",
@@ -46,6 +47,7 @@
     "ember-cli-babel": "^8.2.0",
     "ember-cli-clean-css": "^3.0.0",
     "ember-cli-dependency-checker": "^3.3.3",
+    "ember-cli-deprecation-workflow": "^3.1.0",
     "ember-cli-htmlbars": "^6.3.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-data": "~5.4.0-beta.12",
diff --git a/tests/fixtures/app/embroider-yarn/package.json b/tests/fixtures/app/embroider-yarn/package.json
index 19775f062..717980079 100644
--- a/tests/fixtures/app/embroider-yarn/package.json
+++ b/tests/fixtures/app/embroider-yarn/package.json
@@ -34,6 +34,7 @@
     "@ember/test-helpers": "^4.0.4",
     "@embroider/compat": "^3.8.0",
     "@embroider/core": "^3.5.0",
+    "@embroider/macros": "^1.16.10",
     "@embroider/webpack": "^4.0.9",
     "@eslint/js": "^9.17.0",
     "@glimmer/component": "^2.0.0",
@@ -46,6 +47,7 @@
     "ember-cli-babel": "^8.2.0",
     "ember-cli-clean-css": "^3.0.0",
     "ember-cli-dependency-checker": "^3.3.3",
+    "ember-cli-deprecation-workflow": "^3.1.0",
     "ember-cli-htmlbars": "^6.3.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-data": "~5.4.0-beta.12",
diff --git a/tests/fixtures/app/embroider/package.json b/tests/fixtures/app/embroider/package.json
index 69c1dab62..2c3233c3d 100644
--- a/tests/fixtures/app/embroider/package.json
+++ b/tests/fixtures/app/embroider/package.json
@@ -34,6 +34,7 @@
     "@ember/test-helpers": "^4.0.4",
     "@embroider/compat": "^3.8.0",
     "@embroider/core": "^3.5.0",
+    "@embroider/macros": "^1.16.10",
     "@embroider/webpack": "^4.0.9",
     "@eslint/js": "^9.17.0",
     "@glimmer/component": "^2.0.0",
@@ -46,6 +47,7 @@
     "ember-cli-babel": "^8.2.0",
     "ember-cli-clean-css": "^3.0.0",
     "ember-cli-dependency-checker": "^3.3.3",
+    "ember-cli-deprecation-workflow": "^3.1.0",
     "ember-cli-htmlbars": "^6.3.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-data": "~5.4.0-beta.12",
diff --git a/tests/fixtures/app/npm/package.json b/tests/fixtures/app/npm/package.json
index f9549f377..60df303bd 100644
--- a/tests/fixtures/app/npm/package.json
+++ b/tests/fixtures/app/npm/package.json
@@ -32,6 +32,7 @@
     "@babel/plugin-proposal-decorators": "^7.25.9",
     "@ember/optional-features": "^2.2.0",
     "@ember/test-helpers": "^4.0.4",
+    "@embroider/macros": "^1.16.10",
     "@eslint/js": "^9.17.0",
     "@glimmer/component": "^2.0.0",
     "@glimmer/tracking": "^1.1.2",
@@ -43,6 +44,7 @@
     "ember-cli-babel": "^8.2.0",
     "ember-cli-clean-css": "^3.0.0",
     "ember-cli-dependency-checker": "^3.3.3",
+    "ember-cli-deprecation-workflow": "^3.1.0",
     "ember-cli-htmlbars": "^6.3.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-cli-sri": "^2.1.1",
diff --git a/tests/fixtures/app/pnpm/package.json b/tests/fixtures/app/pnpm/package.json
index cf93e6600..7d80f482a 100644
--- a/tests/fixtures/app/pnpm/package.json
+++ b/tests/fixtures/app/pnpm/package.json
@@ -32,6 +32,7 @@
     "@babel/plugin-proposal-decorators": "^7.25.9",
     "@ember/optional-features": "^2.2.0",
     "@ember/test-helpers": "^4.0.4",
+    "@embroider/macros": "^1.16.10",
     "@eslint/js": "^9.17.0",
     "@glimmer/component": "^2.0.0",
     "@glimmer/tracking": "^1.1.2",
@@ -43,6 +44,7 @@
     "ember-cli-babel": "^8.2.0",
     "ember-cli-clean-css": "^3.0.0",
     "ember-cli-dependency-checker": "^3.3.3",
+    "ember-cli-deprecation-workflow": "^3.1.0",
     "ember-cli-htmlbars": "^6.3.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-cli-sri": "^2.1.1",
diff --git a/tests/fixtures/app/typescript-embroider/package.json b/tests/fixtures/app/typescript-embroider/package.json
index 1bf529b67..f27607cc0 100644
--- a/tests/fixtures/app/typescript-embroider/package.json
+++ b/tests/fixtures/app/typescript-embroider/package.json
@@ -43,6 +43,7 @@
     "@ember/test-helpers": "^4.0.4",
     "@embroider/compat": "^3.8.0",
     "@embroider/core": "^3.5.0",
+    "@embroider/macros": "^1.16.10",
     "@embroider/webpack": "^4.0.9",
     "@eslint/js": "^9.17.0",
     "@glimmer/component": "^2.0.0",
@@ -63,6 +64,7 @@
     "ember-cli-babel": "^8.2.0",
     "ember-cli-clean-css": "^3.0.0",
     "ember-cli-dependency-checker": "^3.3.3",
+    "ember-cli-deprecation-workflow": "^3.1.0",
     "ember-cli-htmlbars": "^6.3.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-data": "~5.4.0-beta.12",
diff --git a/tests/fixtures/app/typescript/package.json b/tests/fixtures/app/typescript/package.json
index 01658914c..f79efeac0 100644
--- a/tests/fixtures/app/typescript/package.json
+++ b/tests/fixtures/app/typescript/package.json
@@ -41,6 +41,7 @@
     "@ember-data/tracking": "~5.4.0-beta.12",
     "@ember/optional-features": "^2.2.0",
     "@ember/test-helpers": "^4.0.4",
+    "@embroider/macros": "^1.16.10",
     "@eslint/js": "^9.17.0",
     "@glimmer/component": "^2.0.0",
     "@glimmer/tracking": "^1.1.2",
@@ -60,6 +61,7 @@
     "ember-cli-babel": "^8.2.0",
     "ember-cli-clean-css": "^3.0.0",
     "ember-cli-dependency-checker": "^3.3.3",
+    "ember-cli-deprecation-workflow": "^3.1.0",
     "ember-cli-htmlbars": "^6.3.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-cli-sri": "^2.1.1",
diff --git a/tests/fixtures/app/yarn/package.json b/tests/fixtures/app/yarn/package.json
index 8c7e48f86..049f10e48 100644
--- a/tests/fixtures/app/yarn/package.json
+++ b/tests/fixtures/app/yarn/package.json
@@ -32,6 +32,7 @@
     "@babel/plugin-proposal-decorators": "^7.25.9",
     "@ember/optional-features": "^2.2.0",
     "@ember/test-helpers": "^4.0.4",
+    "@embroider/macros": "^1.16.10",
     "@eslint/js": "^9.17.0",
     "@glimmer/component": "^2.0.0",
     "@glimmer/tracking": "^1.1.2",
@@ -43,6 +44,7 @@
     "ember-cli-babel": "^8.2.0",
     "ember-cli-clean-css": "^3.0.0",
     "ember-cli-dependency-checker": "^3.3.3",
+    "ember-cli-deprecation-workflow": "^3.1.0",
     "ember-cli-htmlbars": "^6.3.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-cli-sri": "^2.1.1",
diff --git a/tests/unit/debug/deprecate-test.js b/tests/unit/debug/deprecate-test.js
index 7de75c3b0..1863a0b16 100644
--- a/tests/unit/debug/deprecate-test.js
+++ b/tests/unit/debug/deprecate-test.js
@@ -5,6 +5,24 @@ const stripAnsi = require('strip-ansi');
 const { deprecate } = require('../../../lib/debug');
 
 describe('deprecate', function () {
+  let consoleWarn;
+  let deprecations;
+
+  beforeEach(function () {
+    consoleWarn = console.warn;
+    deprecations = [];
+
+    // TODO: This should be updated once we can register deprecation handlers:
+    console.warn = (deprecation) => {
+      // Remove the stack trace:
+      deprecations.push(stripAnsi(deprecation).split('at getStackTrace')[0].trimEnd());
+    };
+  });
+
+  afterEach(function () {
+    console.warn = consoleWarn;
+  });
+
   it('it throws when the description argument is missing', function () {
     expect(() => {
       deprecate();
@@ -132,7 +150,7 @@ describe('deprecate', function () {
   });
 
   it('it does nothing when the condition argument is truthy', function () {
-    let message = deprecate('description', true, {
+    deprecate('description', true, {
       for: 'foo',
       id: 'foo',
       since: {
@@ -142,11 +160,11 @@ describe('deprecate', function () {
       until: '5.0.0',
     });
 
-    expect(message).to.be.undefined;
+    expect(deprecations).to.deep.equal([]);
   });
 
   it('it displays a deprecation message when the condition argument is falsy', function () {
-    let message = deprecate('description', false, {
+    deprecate('description', false, {
       for: 'foo',
       id: 'foo',
       since: {
@@ -156,15 +174,17 @@ describe('deprecate', function () {
       until: '5.0.0',
     });
 
-    expect(stripAnsi(message)).to.be.equal(` DEPRECATION \n
+    expect(deprecations).to.deep.equal([
+      ` DEPRECATION \n
 description
 
 ID     foo
-UNTIL  5.0.0`);
+UNTIL  5.0.0`,
+    ]);
   });
 
   it('it includes the `url` option in the deprecation message when provided', function () {
-    let message = deprecate('description', false, {
+    deprecate('description', false, {
       for: 'foo',
       id: 'foo',
       since: {
@@ -175,12 +195,14 @@ UNTIL  5.0.0`);
       url: 'https://example.com',
     });
 
-    expect(stripAnsi(message)).to.be.equal(` DEPRECATION \n
+    expect(deprecations).to.deep.equal([
+      ` DEPRECATION \n
 description
 
 ID     foo
 UNTIL  5.0.0
-URL    https://example.com`);
+URL    https://example.com`,
+    ]);
   });
 
   it('throws an deprecation if the current ember-cli version is greater than the until version of deprecation', function () {