@autofleet/cli 2.26.1 → 2.27.0-alpha.1
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.
- package/.claude/settings.local.json +9 -0
- package/dist/claude-marketplace/plugins/autofleet/.claude-plugin/plugin.json +1 -1
- package/dist/claude-marketplace/plugins/autofleet/commands/update-packages.md +604 -0
- package/dist/e2e.js +1 -1
- package/dist/git-autofleet.js +1 -1
- package/dist/index.js +17 -18
- package/dist/index.js.map +1 -1
- package/dist/{utils-CjNbANlh.js → utils-BNpnqNAk.js} +2 -2
- package/dist/{utils-CjNbANlh.js.map → utils-BNpnqNAk.js.map} +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,604 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Update all @autofleet packages in a microservice to their latest versions and migrate all breaking changes. Run this command from the root of the microservice you want to update.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Update @autofleet Packages
|
|
6
|
+
|
|
7
|
+
You are migrating a microservice to use the latest versions of all `@autofleet/*` packages. This involves updating package versions AND making code changes to handle breaking API changes across multiple packages.
|
|
8
|
+
|
|
9
|
+
## Instructions
|
|
10
|
+
|
|
11
|
+
Follow these steps **in order**. For each step, first check if the migration applies to this service. If it does, add it to your TODO list, then execute it. Do NOT skip any applicable migration. Do NOT proceed to the next migration until the current one is complete.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Step 0: Scan and update package versions
|
|
16
|
+
|
|
17
|
+
1. Read the service's `package.json` to identify all `@autofleet/*` dependencies currently in use.
|
|
18
|
+
2. Run `autofleet updateAutofleetPackages --yes --quiet` to update all `@autofleet/*` packages to their latest versions non-interactively with minimal output.
|
|
19
|
+
3. After the command completes, run `npm install` to make sure the lockfile is updated.
|
|
20
|
+
4. Build your TODO list: go through each migration section below and check if it applies to this service based on the packages it uses. Create a checklist of all applicable migrations.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Step 1: Migrate @autofleet/super-express
|
|
25
|
+
|
|
26
|
+
**Applies when:** The service has `@autofleet/super-express` in its dependencies.
|
|
27
|
+
|
|
28
|
+
This package changed from a class to a function, and the health/alive endpoint system was completely replaced.
|
|
29
|
+
|
|
30
|
+
### 1.1 Fix the import (CommonJS only)
|
|
31
|
+
|
|
32
|
+
If using CommonJS `require`:
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
// BEFORE
|
|
36
|
+
const SExpress = require('@autofleet/super-express');
|
|
37
|
+
|
|
38
|
+
// AFTER
|
|
39
|
+
const { default: SExpress } = require('@autofleet/super-express');
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
ESM `import SExpress from '@autofleet/super-express'` does not need changing.
|
|
43
|
+
|
|
44
|
+
### 1.2 Change from class instantiation to function call
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
// BEFORE
|
|
48
|
+
const app = new SExpress({ ... });
|
|
49
|
+
|
|
50
|
+
// AFTER
|
|
51
|
+
const app = SExpress({ ... });
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 1.3 Add required `name` and `logger` parameters
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
const app = SExpress({
|
|
58
|
+
name: packageJson.name, // import package.json if not already imported
|
|
59
|
+
logger, // import the logger instance
|
|
60
|
+
// ... other options
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 1.4 Remove `httpLogCb` callback
|
|
65
|
+
|
|
66
|
+
Morgan HTTP logging is now built-in. Delete the entire `httpLogCb` property and its callback function:
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
// DELETE this entire block from the SExpress options:
|
|
70
|
+
httpLogCb(options) {
|
|
71
|
+
logger.info(options.url, {
|
|
72
|
+
httpRequest: {
|
|
73
|
+
status: options.status,
|
|
74
|
+
requestUrl: options.url,
|
|
75
|
+
requestMethod: options.method,
|
|
76
|
+
responseSize: options['content-length'],
|
|
77
|
+
latency: {
|
|
78
|
+
seconds: parseInt(options['response-time'], 10) / 1000,
|
|
79
|
+
nanos: parseInt(options['response-time'], 10) * 1000000,
|
|
80
|
+
},
|
|
81
|
+
userAgent: options['user-agent'],
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 1.5 Replace `aliveEndpointOptions` with `healthManagerOptions`
|
|
88
|
+
|
|
89
|
+
The old `aliveEndpointOptions` and manual `nitur.aliveEndpoint()` are replaced by `healthManagerOptions`. Add all service clients (sequelize, redis, rabbit, events) to the health manager:
|
|
90
|
+
|
|
91
|
+
```js
|
|
92
|
+
// BEFORE (option A — as SExpress option)
|
|
93
|
+
aliveEndpointOptions: { sequelize }
|
|
94
|
+
|
|
95
|
+
// BEFORE (option B — manual endpoint)
|
|
96
|
+
app.get('/alive', nitur.aliveEndpoint({ sequelize, redis, rabbit }));
|
|
97
|
+
|
|
98
|
+
// AFTER — replace with healthManagerOptions in SExpress call:
|
|
99
|
+
healthManagerOptions: {
|
|
100
|
+
clients: {
|
|
101
|
+
sequelize: { connection: sequelize },
|
|
102
|
+
redis: { connection: redis }, // include if service uses redis
|
|
103
|
+
rabbit: { connection: rabbit }, // include if service uses rabbit
|
|
104
|
+
events: { connection: events }, // include if service uses events — see Step 4
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Only include clients that the service actually uses. The events instance must be created first — see Step 4.
|
|
110
|
+
|
|
111
|
+
### 1.6 Remove manual `/alive` endpoint and nitur import
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
// DELETE these lines:
|
|
115
|
+
const nitur = require('@autofleet/nitur');
|
|
116
|
+
// ...
|
|
117
|
+
app.get('/alive', nitur.aliveEndpoint({ sequelize, redis, rabbit }));
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The `/alive` and `/ready` endpoints are now automatically added by super-express when `healthManagerOptions` is provided.
|
|
121
|
+
|
|
122
|
+
### 1.7 Remove `enableTracing()`, `zehut.middleware()`, and `addContextMiddleware()`
|
|
123
|
+
|
|
124
|
+
Super-express now handles all tracing internally (via its `tracing: true` default option). Remove these from the app file:
|
|
125
|
+
|
|
126
|
+
```js
|
|
127
|
+
// DELETE all of these:
|
|
128
|
+
const { default: zehut, enableTracing } = require('@autofleet/zehut');
|
|
129
|
+
|
|
130
|
+
enableTracing();
|
|
131
|
+
|
|
132
|
+
logger.addContextMiddleware(() => ({
|
|
133
|
+
traceId: zehut.outbreak.getCurrentContext()?.context?.get('x-trace-id'),
|
|
134
|
+
}));
|
|
135
|
+
|
|
136
|
+
app.use(zehut.middleware({
|
|
137
|
+
eagerLoadUserPermissions: true,
|
|
138
|
+
}));
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### 1.8 Add `morgan` as a dependency
|
|
142
|
+
|
|
143
|
+
If `morgan` is not already in the service's `package.json`, add it:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
npm install morgan
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 1.9 Remove `/alive` endpoint tests
|
|
150
|
+
|
|
151
|
+
Search for tests that hit the `/alive` endpoint and remove them. The endpoint behavior has changed (now managed by HealthManager internally):
|
|
152
|
+
|
|
153
|
+
```js
|
|
154
|
+
// DELETE test blocks like:
|
|
155
|
+
it('has /alive endpoint', async () => {
|
|
156
|
+
const get = await request(app).get('/alive');
|
|
157
|
+
expect(get).toEqual(expect.objectContaining({
|
|
158
|
+
status: 200,
|
|
159
|
+
body: { status: 'ok' },
|
|
160
|
+
}));
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Step 2: Migrate @autofleet/fastify-boilerplate
|
|
167
|
+
|
|
168
|
+
**Applies when:** The service has `@autofleet/fastify-boilerplate` in its dependencies (instead of super-express).
|
|
169
|
+
|
|
170
|
+
The same health manager migration applies:
|
|
171
|
+
|
|
172
|
+
### 2.1 Replace `aliveEndpointOptions` with `healthManagerOptions`
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
// BEFORE
|
|
176
|
+
fastifyBoilerplatePlugin(app, {
|
|
177
|
+
logger,
|
|
178
|
+
aliveEndpointOptions: { sequelize },
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// AFTER
|
|
182
|
+
fastifyBoilerplatePlugin(app, {
|
|
183
|
+
logger,
|
|
184
|
+
healthManagerOptions: {
|
|
185
|
+
clients: {
|
|
186
|
+
sequelize: { connection: sequelize },
|
|
187
|
+
rabbit: { connection: rabbit }, // if used
|
|
188
|
+
events: { connection: events }, // if used — see Step 4
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### 2.2 Note on probe paths
|
|
195
|
+
|
|
196
|
+
The readiness probe path changed from `/alive` to `/ready`. The `/alive` endpoint still exists for liveness checks but `/ready` is the new readiness endpoint. If the service has Helm charts or Kubernetes configs, note that the readiness probe may need updating (this is outside the code scope but flag it to the user).
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Step 3: Migrate @autofleet/logger
|
|
201
|
+
|
|
202
|
+
**Applies when:** Always — all services use the logger.
|
|
203
|
+
|
|
204
|
+
### 3.1 Add serviceName and version to logger initialization
|
|
205
|
+
|
|
206
|
+
Find the logger initialization file (usually `src/logger.ts` or `src/logger.js`):
|
|
207
|
+
|
|
208
|
+
```js
|
|
209
|
+
// BEFORE
|
|
210
|
+
const logger = Logger();
|
|
211
|
+
|
|
212
|
+
// AFTER
|
|
213
|
+
const logger = Logger(undefined, { serviceName: '<SERVICE_NAME>', version: process.env.DD_GIT_COMMIT_SHA });
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Replace `<SERVICE_NAME>` with the actual service name from `package.json` (e.g., `'matching-ms'`, `'license-ms'`).
|
|
217
|
+
|
|
218
|
+
### 3.2 Remove `addContextMiddleware` for trace ID injection
|
|
219
|
+
|
|
220
|
+
This is now handled automatically by super-express/fastify-boilerplate. Find and delete:
|
|
221
|
+
|
|
222
|
+
```js
|
|
223
|
+
// DELETE these lines (they may be in logger.ts, logger.js, or app.ts/app.js):
|
|
224
|
+
import zehut from '@autofleet/zehut';
|
|
225
|
+
// or: const { default: zehut } = require('@autofleet/zehut');
|
|
226
|
+
|
|
227
|
+
logger.addContextMiddleware(() => ({
|
|
228
|
+
traceId: zehut.outbreak.getCurrentContext()?.context?.get('x-trace-id'),
|
|
229
|
+
}));
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
If the `zehut` import was only used for the context middleware, remove the import entirely.
|
|
233
|
+
|
|
234
|
+
### 3.3 (Optional) Add getChildLogger helper
|
|
235
|
+
|
|
236
|
+
If the service would benefit from module-specific loggers:
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
export const getChildLogger = (moduleName: string, metadata?: Record<string, unknown>) =>
|
|
240
|
+
logger.child(moduleName, { module: moduleName, ...metadata });
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Step 4: Migrate @autofleet/events
|
|
246
|
+
|
|
247
|
+
**Applies when:** The service has `@autofleet/events` in its dependencies, OR it's being added as a new dependency (needed for healthManagerOptions).
|
|
248
|
+
|
|
249
|
+
### 4.1 If no events file exists, create one
|
|
250
|
+
|
|
251
|
+
Create `src/events.ts` (TypeScript) or `src/events.js` (JavaScript):
|
|
252
|
+
|
|
253
|
+
**TypeScript (ESM):**
|
|
254
|
+
```ts
|
|
255
|
+
import Events from '@autofleet/events';
|
|
256
|
+
import { getUser, outbreak } from '@autofleet/zehut';
|
|
257
|
+
import logger from './logger';
|
|
258
|
+
|
|
259
|
+
const events = new Events({
|
|
260
|
+
logger,
|
|
261
|
+
getUserId: () => getUser()?.id,
|
|
262
|
+
getTraceId: outbreak.getCurrentContextTraceId,
|
|
263
|
+
enableGracefulShutdown: false,
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
export default events;
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
**JavaScript (CJS):**
|
|
270
|
+
```js
|
|
271
|
+
const { default: Events } = require('@autofleet/events');
|
|
272
|
+
const { getUser } = require('@autofleet/zehut');
|
|
273
|
+
const logger = require('./logger');
|
|
274
|
+
|
|
275
|
+
module.exports = new Events({
|
|
276
|
+
logger,
|
|
277
|
+
getUserId: () => getUser()?.id,
|
|
278
|
+
enableGracefulShutdown: false,
|
|
279
|
+
});
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### 4.2 If events file already exists, update the constructor
|
|
283
|
+
|
|
284
|
+
Add these properties to the Events constructor:
|
|
285
|
+
|
|
286
|
+
```js
|
|
287
|
+
// BEFORE
|
|
288
|
+
module.exports = new Events({ logger });
|
|
289
|
+
|
|
290
|
+
// AFTER
|
|
291
|
+
const { getUser } = require('@autofleet/zehut');
|
|
292
|
+
|
|
293
|
+
module.exports = new Events({
|
|
294
|
+
logger,
|
|
295
|
+
getUserId: () => getUser()?.id,
|
|
296
|
+
enableGracefulShutdown: false,
|
|
297
|
+
});
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**Critical:** `enableGracefulShutdown: false` is required because the health manager (via super-express or fastify-boilerplate) now handles graceful shutdown. Without this, events will try to shut down on its own, causing conflicts.
|
|
301
|
+
|
|
302
|
+
### 4.3 Import events in the app file
|
|
303
|
+
|
|
304
|
+
Make sure to import the events instance in `src/app.ts` or `src/app.js` so it can be passed to `healthManagerOptions.clients.events`:
|
|
305
|
+
|
|
306
|
+
```js
|
|
307
|
+
const events = require('./events');
|
|
308
|
+
// or: import events from './events';
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Step 5: Migrate @autofleet/rabbit
|
|
314
|
+
|
|
315
|
+
**Applies when:** The service has `@autofleet/rabbit` in its dependencies.
|
|
316
|
+
|
|
317
|
+
### 5.1 Add logger and dontGracefulShutdown to constructor
|
|
318
|
+
|
|
319
|
+
Find the rabbit initialization file (usually `src/rabbit/index.ts`, `src/services/rabbit/index.ts`, or similar):
|
|
320
|
+
|
|
321
|
+
```ts
|
|
322
|
+
// BEFORE
|
|
323
|
+
import RabbitMq from '@autofleet/rabbit';
|
|
324
|
+
const rabbit = new RabbitMq();
|
|
325
|
+
|
|
326
|
+
// AFTER
|
|
327
|
+
import RabbitMq from '@autofleet/rabbit';
|
|
328
|
+
import logger from '../logger'; // adjust path based on file location
|
|
329
|
+
|
|
330
|
+
const rabbit = new RabbitMq({
|
|
331
|
+
logger,
|
|
332
|
+
dontGracefulShutdown: true,
|
|
333
|
+
});
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**Critical:** `dontGracefulShutdown: true` is required because the health manager now handles graceful shutdown. Without this flag, rabbit will attempt to shut down independently, causing a double-shutdown conflict.
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Step 6: Migrate @autofleet/node-common Router
|
|
341
|
+
|
|
342
|
+
**Applies when:** The service creates Express routers using `const { Router } = require('express')`.
|
|
343
|
+
|
|
344
|
+
### 6.1 Replace express Router with node-common Router
|
|
345
|
+
|
|
346
|
+
Search ALL files for `require('express')` where `Router` is destructured, or `import { Router } from 'express'`:
|
|
347
|
+
|
|
348
|
+
```js
|
|
349
|
+
// BEFORE
|
|
350
|
+
const { Router } = require('express');
|
|
351
|
+
const router = Router();
|
|
352
|
+
|
|
353
|
+
// AFTER
|
|
354
|
+
const { Router } = require('@autofleet/node-common');
|
|
355
|
+
const logger = require('../../logger'); // adjust relative path
|
|
356
|
+
const router = Router({ logger });
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### 6.2 Update ALL router instantiations
|
|
360
|
+
|
|
361
|
+
Every `Router()` call must receive `{ logger }`. Search for all occurrences of `Router()` across the codebase and update them:
|
|
362
|
+
|
|
363
|
+
```js
|
|
364
|
+
// BEFORE (in any route file)
|
|
365
|
+
const router = Router();
|
|
366
|
+
|
|
367
|
+
// AFTER
|
|
368
|
+
const router = Router({ logger });
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Each file that creates a router needs a logger import. Adjust the relative path based on the file's location relative to the logger module.
|
|
372
|
+
|
|
373
|
+
**Important:** Files that already have `const { Router } = require('express')` just for types or other Express utilities — check if `Router` is actually used. Only update files that call `Router()`.
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## Step 7: Migrate @autofleet/matmon (v3)
|
|
378
|
+
|
|
379
|
+
**Applies when:** The service has `@autofleet/matmon` in its dependencies.
|
|
380
|
+
|
|
381
|
+
### 7.1 Remove all `*Async` Redis method calls
|
|
382
|
+
|
|
383
|
+
Matmon v3 uses redis v4 which has native promise support. All `*Async` suffixed methods are removed:
|
|
384
|
+
|
|
385
|
+
```js
|
|
386
|
+
// BEFORE
|
|
387
|
+
await redis.getAsync(key);
|
|
388
|
+
await redis.setAsync(key, value);
|
|
389
|
+
await redis.delAsync(key);
|
|
390
|
+
|
|
391
|
+
// AFTER
|
|
392
|
+
await redis.get(key);
|
|
393
|
+
await redis.set(key, value);
|
|
394
|
+
await redis.del(key);
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Search for all `Async` suffixed method calls on redis instances and remove the suffix.
|
|
398
|
+
|
|
399
|
+
### 7.2 Logger is now required for RedisCache
|
|
400
|
+
|
|
401
|
+
If the service creates `RedisCache` instances, ensure a logger is passed.
|
|
402
|
+
|
|
403
|
+
### 7.3 Update `getWithCacheSupport` calls
|
|
404
|
+
|
|
405
|
+
The API changed significantly. The key differences are:
|
|
406
|
+
- `logger` is now a required field
|
|
407
|
+
- `cacheKey` should be the full unique cache key (not just a prefix/category name)
|
|
408
|
+
- `cacheGet` callback now receives `(key)` as its first argument
|
|
409
|
+
- `cacheSet` callback now receives `(cacheKey, value)` — the key is passed explicitly
|
|
410
|
+
|
|
411
|
+
```js
|
|
412
|
+
// BEFORE
|
|
413
|
+
const CACHE_KEY = 'scoreAdjustment';
|
|
414
|
+
const getFromCache = (id, type) => cache.get(`${id}:${type}`);
|
|
415
|
+
const setInCache = (id, type, value) => cache.set(`${id}:${type}`, value);
|
|
416
|
+
|
|
417
|
+
const result = await getWithCacheSupport({
|
|
418
|
+
cacheKey: CACHE_KEY,
|
|
419
|
+
cacheGet: () => getFromCache(businessModelId, optimizeFor),
|
|
420
|
+
cacheSet: (value) => setInCache(businessModelId, optimizeFor, value),
|
|
421
|
+
fetching: () => fetchFromDb(businessModelId, optimizeFor),
|
|
422
|
+
skipCache,
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
// AFTER
|
|
426
|
+
const createCacheKey = (id, type) => `scoreAdjustment:${id}:${type}`;
|
|
427
|
+
|
|
428
|
+
const result = await getWithCacheSupport({
|
|
429
|
+
logger,
|
|
430
|
+
cacheKey: createCacheKey(businessModelId, optimizeFor),
|
|
431
|
+
cacheGet: (key) => scoreAdjustmentCache.get(key),
|
|
432
|
+
cacheSet: (cacheKey, value) => scoreAdjustmentCache.set(cacheKey, value),
|
|
433
|
+
fetching: () => fetchFromDb(businessModelId, optimizeFor),
|
|
434
|
+
skipCache,
|
|
435
|
+
});
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### 7.4 Update `getMultipleWithCache` calls
|
|
439
|
+
|
|
440
|
+
Same callback signature changes apply to `getMultipleWithCache` — update `cacheGet` and `cacheSet` callbacks to accept the key parameter.
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## Step 8: Migrate @autofleet/sequelize-utils
|
|
445
|
+
|
|
446
|
+
**Applies when:** The service uses `registerModelEventHooks` from `@autofleet/sequelize-utils`.
|
|
447
|
+
|
|
448
|
+
### 8.1 Pass events instance to registerModelEventHooks
|
|
449
|
+
|
|
450
|
+
```ts
|
|
451
|
+
// BEFORE
|
|
452
|
+
import sequelizeUtilsInit from '@autofleet/sequelize-utils';
|
|
453
|
+
const { registerModelEventHooks, transactionWithRetry } = sequelizeUtilsInit(sequelize);
|
|
454
|
+
|
|
455
|
+
registerModelEventHooks(modelEventsTableMapping);
|
|
456
|
+
|
|
457
|
+
// AFTER
|
|
458
|
+
import sequelizeUtilsInit from '@autofleet/sequelize-utils';
|
|
459
|
+
import events from '../../events'; // adjust path — import the events instance from Step 4
|
|
460
|
+
const { registerModelEventHooks, transactionWithRetry } = sequelizeUtilsInit(sequelize);
|
|
461
|
+
|
|
462
|
+
registerModelEventHooks(modelEventsTableMapping, events);
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
## Step 9: Update database config
|
|
468
|
+
|
|
469
|
+
**Applies when:** The service has `src/config/config.js` with Sequelize database configuration.
|
|
470
|
+
|
|
471
|
+
### 9.1 Change password default from `null` to empty string
|
|
472
|
+
|
|
473
|
+
Find all environments in the config file and update:
|
|
474
|
+
|
|
475
|
+
```js
|
|
476
|
+
// BEFORE
|
|
477
|
+
password: env.DB_PASSWORD || null,
|
|
478
|
+
|
|
479
|
+
// AFTER
|
|
480
|
+
password: env.DB_PASSWORD || '',
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
Apply this change to ALL environments in the config: `development`, `test`, and `production`.
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
## Step 10: Remove New Relic
|
|
488
|
+
|
|
489
|
+
**Applies when:** The service has a `newrelic.js` file at the project root OR has `newrelic` in its dependencies.
|
|
490
|
+
|
|
491
|
+
### 10.1 Delete the `newrelic.js` file
|
|
492
|
+
|
|
493
|
+
Delete the file at the project root:
|
|
494
|
+
|
|
495
|
+
```bash
|
|
496
|
+
rm newrelic.js
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### 10.2 Remove New Relic initialization from entry point
|
|
500
|
+
|
|
501
|
+
Find the service entry point (usually `src/index.js` or `src/index.ts`) and remove:
|
|
502
|
+
|
|
503
|
+
```js
|
|
504
|
+
// DELETE these lines:
|
|
505
|
+
if (process.env.NEW_RELIC_KEY) {
|
|
506
|
+
require('newrelic'); // eslint-disable-line
|
|
507
|
+
}
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
### 10.3 Uninstall the newrelic package
|
|
511
|
+
|
|
512
|
+
```bash
|
|
513
|
+
npm uninstall newrelic
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
---
|
|
517
|
+
|
|
518
|
+
## Step 11: Remove obsolete dependencies
|
|
519
|
+
|
|
520
|
+
**Applies when:** The service has any of these in `package.json`.
|
|
521
|
+
|
|
522
|
+
Check for and remove:
|
|
523
|
+
|
|
524
|
+
1. **`worker-threads-pool`** — no longer used:
|
|
525
|
+
```bash
|
|
526
|
+
npm uninstall worker-threads-pool
|
|
527
|
+
```
|
|
528
|
+
Also delete `src/threads-pool.js` if it exists.
|
|
529
|
+
|
|
530
|
+
2. **`newrelic`** — already handled in Step 10 above.
|
|
531
|
+
|
|
532
|
+
---
|
|
533
|
+
|
|
534
|
+
## Step 12: Update Vitest/test configuration
|
|
535
|
+
|
|
536
|
+
**Applies when:** The service uses Vitest (`vitest.config.ts` exists).
|
|
537
|
+
|
|
538
|
+
### 12.1 Add resolve alias for joi
|
|
539
|
+
|
|
540
|
+
In `vitest.config.ts`, add a resolve alias to prevent Joi resolution issues:
|
|
541
|
+
|
|
542
|
+
```ts
|
|
543
|
+
export default defineConfig({
|
|
544
|
+
// ... existing config
|
|
545
|
+
resolve: {
|
|
546
|
+
alias: {
|
|
547
|
+
joi: 'joi',
|
|
548
|
+
},
|
|
549
|
+
},
|
|
550
|
+
// ...
|
|
551
|
+
});
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
### 12.2 Add SSR noExternal for @autofleet packages
|
|
555
|
+
|
|
556
|
+
Ensure `@autofleet/*` packages are not externalized during testing:
|
|
557
|
+
|
|
558
|
+
```ts
|
|
559
|
+
export default defineConfig({
|
|
560
|
+
// ... existing config
|
|
561
|
+
ssr: {
|
|
562
|
+
noExternal: [/@autofleet\/.*/],
|
|
563
|
+
},
|
|
564
|
+
// ...
|
|
565
|
+
});
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
### 12.3 Remove `/alive` endpoint tests
|
|
569
|
+
|
|
570
|
+
If there are tests asserting on the `/alive` endpoint returning `{ status: 'ok' }`, remove them — the endpoint now returns a different response format from HealthManager.
|
|
571
|
+
|
|
572
|
+
---
|
|
573
|
+
|
|
574
|
+
## Step 13: Settings (non-async setLocal)
|
|
575
|
+
|
|
576
|
+
**Applies when:** The service uses `@autofleet/settings` and calls `await settings.setLocal(...)`.
|
|
577
|
+
|
|
578
|
+
### 13.1 Remove `await` from `settings.setLocal` calls
|
|
579
|
+
|
|
580
|
+
`setLocal` is no longer async:
|
|
581
|
+
|
|
582
|
+
```js
|
|
583
|
+
// BEFORE
|
|
584
|
+
await settings.setLocal('matching.driverShiftMarginMinutes', [{ businessModelId }], 0);
|
|
585
|
+
|
|
586
|
+
// AFTER
|
|
587
|
+
settings.setLocal('matching.driverShiftMarginMinutes', [{ businessModelId }], 0);
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
Search for all `await settings.setLocal` and `await.*setLocal` patterns and remove the `await`.
|
|
591
|
+
|
|
592
|
+
---
|
|
593
|
+
|
|
594
|
+
## Step 14: Verify the migration
|
|
595
|
+
|
|
596
|
+
After completing all applicable migrations:
|
|
597
|
+
|
|
598
|
+
1. **Install dependencies:** `npm install`
|
|
599
|
+
2. **Build:** Run the service's build command (`npm run build` or `npx tsc`) and fix any compilation errors
|
|
600
|
+
3. **Lint:** Run `npm run lint` and fix any lint errors
|
|
601
|
+
4. **Test:** Run `npm test` and fix any failing tests
|
|
602
|
+
5. **Start:** Verify the service starts locally without errors
|
|
603
|
+
|
|
604
|
+
If any step fails, read the error carefully — it likely points to a migration step that was missed or incompletely applied. Go back through the checklist and verify each applicable migration was fully completed.
|
package/dist/e2e.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{C as e,c as t,i as n,l as r,n as i,x as a}from"./utils-
|
|
2
|
+
import{C as e,c as t,i as n,l as r,n as i,x as a}from"./utils-BNpnqNAk.js";import o from"node:path";import s from"p-retry";const c=[`identity-ms`,`vehicle-ms`,`ride-ms`,`vehicle-live-data-ms`,`pricing-ms`,`payment-ms`,`route-plan-ms`,`task-ms`,`audit-ms`,`pgweb`,`placement-ms`,`demand-prediction-ms`,`control-center-ms`,`setting-ms`,`api-gateway-ms`],l={start:`--e2eBranch=<branchName> --branches="{\\"ride-ms\\": \\"AUT-7070\\"}"`,getIpsForEnv:`--variationId=<yourVariationUuid> --cluster=<dev1/e2eManager>`},u=e=>Object.keys(l).includes(e),{positionals:d,values:f,help:p}=e({strict:!0,binName:`autofleet-e2e`,allowPositionals:!0,options:{e2eBranch:{type:`string`,default:`master`,description:`Name of e2e branch`},branches:{type:`string`,default:``,description:`"ride-ms": "AUT-7070"`},cluster:{type:`string`,short:`c`,description:`The cluster name. One of dev1, e2eManager, expManager`},variationId:{type:`string`,short:`i`,description:`The variation id`}},commands:l});d.length||(console.log(p),process.exit(0));const[m]=d;if(u(m)||n(Error(`Command ${m} does not exist`),p),m===`start`){let e=(f.branches?.replace(`{`,` `)||``).replace(/[^a-z0-9]/gi,``),t=`${o.resolve()}/bin/utils/e2e.sh`,n=`${o.resolve()}/e2e.sh`;r({newFilePath:n,filePath:t,linesToReplace:[{find:`$E2E_BRANCH_PLACE_HOLDER$`,replace:f.e2eBranch},{find:`$BRANCHES_PLACE_HOLDER$`,replace:f.branches},{find:`$NAME_PLACE_HOLDER$`,replace:e}]}),await a(`chmod`,[`+x ${n} && ${n}`]),console.log(`finished e2e`)}const{cluster:h,variationId:g}=f;h||n(Error(`cluster required`),p),g||n(Error(`variationId required`),p);let _;try{_=await i({clusterName:h,variationId:g})}catch(e){n(e)}m===`getIpsForEnv`&&(await Promise.all(c.map(e=>a(`kubectl`,[`annotate`,_,`service`,e,`cloud.google.com/load-balancer-type-`],{print:!1}))),await Promise.all(c.map(e=>a(`kubectl`,[`patch`,`svc`,_,e,`-p`,`{"spec": {"type": "LoadBalancer"}}`],{print:!1}))),console.log(`exposed services successfully. the services are now creating public ips.`),await s(async()=>{let{stdout:e}=await a(`kubectl`,[_,`get`,`services`],{print:!1}),n=t(e);if(n.some(e=>e.includes(`<pending>`)))throw Error(`Some services are still pending`);n.forEach(e=>console.log(e))},{retries:10,factor:1,maxTimeout:5e3,randomize:!0}),process.exit(0));export{};
|
|
3
3
|
//# sourceMappingURL=e2e.js.map
|
package/dist/git-autofleet.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{C as e,_ as t,g as n,h as r,i,m as a,v as o,x as s,y as c}from"./utils-
|
|
2
|
+
import{C as e,_ as t,g as n,h as r,i,m as a,v as o,x as s,y as c}from"./utils-BNpnqNAk.js";import{basename as l,sep as u}from"node:path";import{readdir as d}from"node:fs/promises";import{randomUUID as f}from"node:crypto";const p=[`premajor`,`preminor`,`prepatch`,`prerelease`],m=[`major`,`minor`,`patch`,...p],h={bumpVersion:`[${m.join(`|`)}]`,openPR:`Opens github UI for creating a PR from the current branch.`,releaseBeta:`Bumps version if needed, and publishes a beta release to NPM registry.`},g=e=>Object.keys(h).includes(e),_=async({versionType:e,packageName:t,preReleaseId:n=``})=>{let{stdout:r}=await s(`npm`,[`version`,e,`--no-git-tag-version`,`--preid`,n],{print:!1,cwd:t?`.${u}packages${u}${t}`:void 0});return await s(`git`,[`add`,`package*`],{print:!1}),await s(`git`,[`commit`,`-m`,`${e} version: ${r}`],{print:!1}),console.log(`Created commit for version bump: ${e}. Version is now ${r}`),r},v=async e=>{let t=await c(),{default:{version:n}}=await import(`${e?`${t}${u}packages${u}${e}`:t}${u}package.json`,{assert:{type:`json`},with:{type:`json`}});return n.replace(/\d+\.\d+\.\d+(?:-beta-([\w]+)?\.\d+)?/,`$1`)},{positionals:y,help:b}=e({strict:!0,binName:`git autofleet`,allowPositionals:!0,options:{},commands:h});y.length||(console.log(b),process.exit(0));const[x,S,C]=y;if(g(x)||i(Error(`Command ${x} does not exist`),b),x===`openPR`){let[e,t]=await Promise.all([c(),o()]);await s(`open`,[`https://github.com/Autofleet/${l(e)}/compare/${t}?expand=1`],{print:!1}),process.exit(0)}async function w(){let e=await c();return e.split(u).pop()===`autorepo`?e:!1}async function T({message:e,pathIfAutorepo:t}){t??=await w();let r=C;if(t){let a=(await d(`${t}${u}packages`)).filter(e=>!e.startsWith(`.`));r?a.includes(r)||i(Error(`Package name ${r} does not exist in autorepo packages`),b):r=await n({message:e,choices:a.map(e=>({name:e,value:e}))}),r||i(Error(`No package name provided, exiting...`),b)}return r}if(x===`bumpVersion`){let e=await T({message:`Which package do you want to bump?`}),t=S||await n({message:`Which version type do you want to bump?`,choices:(x===`bumpVersion`?m:p).map(e=>({name:e,value:e}))});t||i(Error(`Must explicitly define version type.\n\tVersion type can be one of: ${m.join(`, `)}`),b);let r=await o();[`main`,`master`].includes(r)&&(await a(`Are you sure you want to bump version on main branch?`)||process.exit(0)),await _({versionType:t,packageName:e}),process.exit(0)}if(x===`releaseBeta`){let e=await w(),n=await T({message:`Which package do you want to release?`,pathIfAutorepo:e});S&&!p.includes(S)&&i(Error(`Invalid version type: ${S}\n\tVersion must be a prerelease type. (${p.join(`, `)})`),b);let c=await o();[`main`,`master`].includes(c)&&i(Error(`Cannot release beta from main branch`),b);let l=n?`.${u}packages${u}${n}`:void 0,d=!(await t(n?`.${u}packages${u}${n}${u}package.json`:`package.json`)).split(`
|
|
3
3
|
`).some(e=>/^\+\s*"version":\s*"\d+\.\d+\.\d+(?:-(?:[\w-]+\.)?\d+)?",/.test(e))||await a(`Version already bumped on branch. Should version be re-bumped?`),m=d&&await v(n),h=d&&await _({versionType:S||`prerelease`,preReleaseId:`beta-${m||f().split(`-`)[0]}`,packageName:n}),g=e?`pnpm`:`npm`;await s(g,[`run`,`build`],{cwd:l});let y=await r({message:`In case your token requires an OTP, please enter it:`});try{await s(g,[`publish`,`--tag`,`beta`,`--@autofleet:registry=https://registry.npmjs.org`,...y?[`--otp`,y]:[],...e?[`--no-git-checks`]:[]],{cwd:l})}catch(e){console.error(e),i(`Failed to publish beta version`)}if(h)console.log(`Published beta version with new version: ${h}`);else{let{stdout:e}=await s(g,[`info`,`.`,`version`],{print:!1,cwd:l});console.log(`Published beta version with existing version: ${e}`)}process.exit(0)}export{};
|
|
4
4
|
//# sourceMappingURL=git-autofleet.js.map
|