Skip to content

Commit dd3b889

Browse files
Release: worker@1.23.4 cli@1.33.0 (#1363)
* update the worker to node 24 (#1357) * update the worker to node 24 * update docker docs * changeset * Worker: fix an issue with batch logging (#1353) * set min-release-age * versions * debugging flaky test * fix an issue where the batch is never clear * fix a timing issue when sending batch events Big help from claude * logging * add a bunch of more controlled unit tests * test on interrupt * update and fix tests I think this this fixes the actual issue - I just want more good focused tests now * tidy logging * more tests * changeset * types * remove only * run tests in serial * worker: tweak event processor and be sure to reset timeout on batch * remove comment * remove more comments * feat: update usage of getActiveProject to getCheckedOutProject (#1360) * feat: update getActiveProject to getCheckedOutProject * feat: back to active project * chore: rename getActiveProject to getTrackedProject * feat: deploy should use getTrackedProject * chore: getCheckedout return undefined like getActiveprojects * fix: types * feat: update removed & renamed workflows on checkout (#1358) * tests: remove unwanted fields * feat: use currentProject * tests: remove fields * versions --------- Co-authored-by: Farhan Y. <yahyafarhan48@gmail.com>
1 parent fd58873 commit dd3b889

File tree

19 files changed

+801
-103
lines changed

19 files changed

+801
-103
lines changed

.claude/command-refactor.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Use `src/projects/list.ts` as the reference pattern for all refactored commands.
1313
Create a new file in `src/projects/<command-name>.ts` that consolidates all the existing command files.
1414

1515
**Key elements:**
16+
1617
- Import `yargs`, `ensure`, `build`, `Logger`, and options from `../options`
1718
- Define a `<CommandName>Options` type that picks required fields from `Opts`
1819
- Create an `options` array with the required options (e.g., `[o.workflow, o.workspace, o.workflowMappings]`)
@@ -24,6 +25,7 @@ Create a new file in `src/projects/<command-name>.ts` that consolidates all the
2425
- Export a named `handler` function that takes `(options: <CommandName>Options, logger: Logger)`
2526

2627
**Example structure:**
28+
2729
```typescript
2830
import yargs from 'yargs';
2931
import { Workspace } from '@openfn/project';
@@ -88,23 +90,26 @@ export const projectsCommand = {
8890
Make three changes:
8991

9092
**a) Remove the old import** (if it exists):
93+
9194
```typescript
9295
// Remove: import commandName from './<command>/handler';
9396
```
9497

9598
**b) Add to CommandList type:**
99+
96100
```typescript
97101
export type CommandList =
98102
| 'apollo'
99103
// ...
100104
| 'project-list'
101105
| 'project-version'
102-
| 'project-<command-name>' // Add this line
106+
| 'project-<command-name>' // Add this line
103107
| 'test'
104108
| 'version';
105109
```
106110

107111
**c) Add to handlers object:**
112+
108113
```typescript
109114
const handlers = {
110115
// ...
@@ -121,6 +126,7 @@ If the old command was referenced elsewhere in the handlers object (like `projec
121126
### 5. Delete the Old Command Folder
122127

123128
Remove the old command directory:
129+
124130
```bash
125131
rm -rf packages/cli/src/<command-name>
126132
```
@@ -142,6 +148,7 @@ import checkoutCommand from './checkout/command';
142148
```
143149

144150
The command will be registered with yargs:
151+
145152
```typescript
146153
.command(projectsCommand)
147154
.command(mergeCommand) // Top-level alias
@@ -159,18 +166,21 @@ This is different from the `install`/`repo install` pattern, where both entries
159166
## Common Patterns
160167

161168
### Options to Use
169+
162170
- Always include `o.workspace` for project-related commands
163171
- Use `o.workflow` for workflow-specific operations
164172
- Include `o.json` if the command supports JSON output
165173
- Include `o.log` for commands that need detailed logging
166174

167175
### Handler Pattern
176+
168177
- Use `new Workspace(options.workspace)` to access the workspace
169178
- Check `workspace.valid` before proceeding
170-
- Use `workspace.getActiveProject()` to get the current project
179+
- Use `workspace.getTrackedProject()` to get the current project
171180
- Use appropriate logger methods: `logger.info()`, `logger.error()`, `logger.success()`
172181

173182
### Testing Pattern
183+
174184
If the old command has tests, they need to be refactored:
175185

176186
1. **Create new test file**: Move from `test/<command>/handler.test.ts` to `test/projects/<command>.test.ts`
@@ -181,6 +191,7 @@ If the old command has tests, they need to be refactored:
181191
4. **Delete old test folder**: Remove `test/<command>` directory
182192

183193
**Example changes:**
194+
184195
```typescript
185196
// Before:
186197
import mergeHandler from '../../src/merge/handler';
@@ -194,6 +205,7 @@ await mergeHandler({ command: 'project-merge', ... }, logger);
194205
## Checklist
195206

196207
### Basic Refactoring
208+
197209
- [ ] Create new file in `src/projects/<command-name>.ts`
198210
- [ ] Define `<CommandName>Options` type
199211
- [ ] Export default command object with `ensure('project-<command-name>', options)`
@@ -206,13 +218,15 @@ await mergeHandler({ command: 'project-merge', ... }, logger);
206218
- [ ] Delete old command folder
207219

208220
### Testing (if applicable)
221+
209222
- [ ] Create new test file in `test/projects/<command-name>.test.ts`
210223
- [ ] Update import to use `{ handler } from '../../src/projects/<command-name>'`
211224
- [ ] Update all `command: '<command>'` to `command: 'project-<command>'` in test cases
212225
- [ ] Delete old test folder `test/<command>`
213226
- [ ] Run tests to verify they pass
214227

215228
### Additional Steps for Top-Level Aliasing
229+
216230
- [ ] Import command directly in `src/cli.ts` (e.g., `import mergeCommand from './projects/merge'`)
217231
- [ ] Register the imported command with `.command(mergeCommand)`
218232
- [ ] Verify NO duplicate entries in `src/commands.ts` - only `project-<command-name>` should exist, not `<command-name>`

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM node:22-alpine AS base
1+
FROM node:24-alpine AS base
22
ENV PNPM_HOME="/pnpm"
33
ENV PATH="$PNPM_HOME:$PATH"
44
RUN corepack enable

integration-tests/worker/test/exit-reasons.test.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const run = async (attempt) => {
3434
});
3535
};
3636

37-
test('crash: syntax error', async (t) => {
37+
test.serial('crash: syntax error', async (t) => {
3838
const attempt = {
3939
id: crypto.randomUUID(),
4040
jobs: [
@@ -54,7 +54,7 @@ test('crash: syntax error', async (t) => {
5454
});
5555

5656
// https://github.com/OpenFn/kit/issues/1045
57-
test('crash: reference error', async (t) => {
57+
test.serial('crash: reference error', async (t) => {
5858
const attempt = {
5959
id: crypto.randomUUID(),
6060
jobs: [
@@ -78,7 +78,7 @@ test('crash: reference error', async (t) => {
7878
});
7979

8080
// https://github.com/OpenFn/kit/issues/758
81-
test('crash: job not found', async (t) => {
81+
test.serial('crash: job not found', async (t) => {
8282
lightning.addDataclip('x', {});
8383

8484
const attempt = {
@@ -102,7 +102,7 @@ test('crash: job not found', async (t) => {
102102
t.regex(error_message, /could not find start job: y/i);
103103
});
104104

105-
test('exception: autoinstall error', async (t) => {
105+
test.serial('exception: autoinstall error', async (t) => {
106106
const attempt = {
107107
id: crypto.randomUUID(),
108108
jobs: [
@@ -125,7 +125,7 @@ test('exception: autoinstall error', async (t) => {
125125
);
126126
});
127127

128-
test('exception: bad credential (not found)', async (t) => {
128+
test.serial('exception: bad credential (not found)', async (t) => {
129129
const attempt = {
130130
id: crypto.randomUUID(),
131131
jobs: [
@@ -154,7 +154,7 @@ test('exception: bad credential (not found)', async (t) => {
154154
);
155155
});
156156

157-
test('exception: credential timeout', async (t) => {
157+
test.serial('exception: credential timeout', async (t) => {
158158
const attempt = {
159159
id: crypto.randomUUID(),
160160
jobs: [
@@ -177,7 +177,7 @@ test('exception: credential timeout', async (t) => {
177177
);
178178
});
179179

180-
test('kill: oom (small, kill worker)', async (t) => {
180+
test.serial('kill: oom (small, kill worker)', async (t) => {
181181
const attempt = {
182182
id: crypto.randomUUID(),
183183
jobs: [
@@ -201,7 +201,8 @@ test('kill: oom (small, kill worker)', async (t) => {
201201
t.is(error_message, 'Run exceeded maximum memory usage');
202202
});
203203

204-
test('kill: oom (large, kill vm)', async (t) => {
204+
// TODO this is failing locally... is it OK in CI?
205+
test.serial('kill: oom (large, kill vm)', async (t) => {
205206
const attempt = {
206207
id: crypto.randomUUID(),
207208
jobs: [
@@ -225,7 +226,7 @@ test('kill: oom (large, kill vm)', async (t) => {
225226
t.is(error_message, 'Run exceeded maximum memory usage');
226227
});
227228

228-
test('crash: process.exit() triggered by postgres', async (t) => {
229+
test.serial('crash: process.exit() triggered by postgres', async (t) => {
229230
const attempt = {
230231
id: crypto.randomUUID(),
231232
jobs: [

packages/cli/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# @openfn/cli
22

3+
## 1.33.0
4+
5+
### Minor Changes
6+
7+
- 6829bdc: Remove renamed/deleted workflows or steps during checkout
8+
39
## 1.32.0
410

511
### Minor Changes

packages/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@openfn/cli",
3-
"version": "1.32.0",
3+
"version": "1.33.0",
44
"description": "CLI devtools for the OpenFn toolchain",
55
"engines": {
66
"node": ">=18",

packages/cli/src/projects/checkout.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ export const handler = async (options: CheckoutOptions, logger?: Logger) => {
4646
// TODO: try to retain the endpoint for the projects
4747
const { project: _, ...config } = workspace.getConfig() as any;
4848

49-
const currentProject = workspace.getActiveProject();
50-
49+
const currentProject = await workspace.getCheckedOutProject();
5150
// get the project
5251
let switchProject;
5352
if (/\.(yaml|json)$/.test(projectIdentifier)) {
@@ -108,7 +107,7 @@ export const handler = async (options: CheckoutOptions, logger?: Logger) => {
108107
if (options.clean) {
109108
await rimraf(workspace.workflowsPath);
110109
} else {
111-
await tidyWorkflowDir(currentProject!, switchProject);
110+
await tidyWorkflowDir(currentProject, switchProject, false, workspacePath);
112111
}
113112

114113
// write the forked from map

packages/cli/src/projects/deploy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ export async function handler(options: DeployOptions, logger: Logger) {
251251
// We need track alias in openfn.yaml to make this easier (and tracked in from fs)
252252
const ws = new Workspace(options.workspace || '.');
253253

254-
const active = ws.getActiveProject();
254+
const active = ws.getTrackedProject();
255255
const alias = options.alias ?? active?.alias;
256256

257257
const localProject = await Project.from('fs', {

packages/cli/src/projects/list.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export const handler = async (options: ProjectListOptions, logger: Logger) => {
3939

4040
logger.always(`Available openfn projects\n\n${workspace
4141
.list()
42-
.map((p) => describeProject(p, p === workspace.getActiveProject()))
42+
.map((p) => describeProject(p, p === workspace.getTrackedProject()))
4343
.join('\n\n')}
4444
`);
4545
};

packages/cli/src/projects/merge.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export const handler = async (options: MergeOptions, logger: Logger) => {
7171
logger.debug('Loading target project from path', basePath);
7272
targetProject = await Project.from('path', basePath);
7373
} else {
74-
targetProject = workspace.getActiveProject()!;
74+
targetProject = workspace.getTrackedProject()!;
7575
if (!targetProject) {
7676
logger.error(`No project currently checked out`);
7777
return;

packages/cli/src/projects/util.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import path from 'node:path';
2+
import fs from 'node:fs';
23
import { mkdir, writeFile } from 'node:fs/promises';
34
import { Provisioner } from '@openfn/lexicon/lightning';
45
import { fetch } from 'undici';
@@ -214,7 +215,8 @@ class DeployError extends Error {
214215
export async function tidyWorkflowDir(
215216
currentProject: Project | undefined,
216217
incomingProject: Project | undefined,
217-
dryRun = false
218+
dryRun = false,
219+
dirPath = '.'
218220
) {
219221
if (!currentProject || !incomingProject) {
220222
return [];
@@ -232,7 +234,15 @@ export async function tidyWorkflowDir(
232234
}
233235

234236
if (!dryRun) {
235-
await rimraf(toRemove);
237+
const abs = (p: string) => path.join(dirPath, p);
238+
await rimraf(toRemove.map(abs));
239+
240+
const dirs = new Set(toRemove.map((f) => path.dirname(f)));
241+
for (const dir of Array.from(dirs)) {
242+
try {
243+
fs.rmdirSync(abs(dir)); // throws when not empty
244+
} catch {}
245+
}
236246
}
237247

238248
// Return and sort for testing

0 commit comments

Comments
 (0)