From 3d4908805e1bcaf1d44d09105f1008a3b8c46667 Mon Sep 17 00:00:00 2001 From: Farhan Yahaya Date: Fri, 20 Feb 2026 07:54:27 +0000 Subject: [PATCH 01/12] feat: redirect to v2 when openfn.yaml exists --- packages/cli/src/deploy/handler.ts | 10 ++++++++++ packages/cli/src/pull/handler.ts | 9 +++++++++ packages/cli/src/util/file-exists.ts | 10 ++++++++++ 3 files changed, 29 insertions(+) create mode 100644 packages/cli/src/util/file-exists.ts diff --git a/packages/cli/src/deploy/handler.ts b/packages/cli/src/deploy/handler.ts index c61b70ba9..a3e943c23 100644 --- a/packages/cli/src/deploy/handler.ts +++ b/packages/cli/src/deploy/handler.ts @@ -8,6 +8,8 @@ import { import type { Logger } from '../util/logger'; import { DeployOptions } from './command'; import * as beta from '../projects/deploy'; +import path from 'node:path'; +import { fileExists } from '../util/file-exists'; export type DeployFn = typeof deploy; @@ -48,6 +50,14 @@ async function deployHandler( config.endpoint = process.env['OPENFN_ENDPOINT']; } + const final_path = path.join( + options.projectPath ?? process.cwd(), + 'openfn.yaml' + ); + if (await fileExists(final_path)) { + return beta.handler(options, logger); + } + logger.debug('Deploying with config', config); logger.info(`Deploying`); diff --git a/packages/cli/src/pull/handler.ts b/packages/cli/src/pull/handler.ts index fe96e7188..79c7b604e 100644 --- a/packages/cli/src/pull/handler.ts +++ b/packages/cli/src/pull/handler.ts @@ -11,6 +11,7 @@ import { import type { Logger } from '../util/logger'; import { PullOptions } from '../pull/command'; import beta from '../projects/pull'; +import { fileExists } from '../util/file-exists'; async function pullHandler(options: PullOptions, logger: Logger) { if (options.beta) { @@ -31,6 +32,14 @@ async function pullHandler(options: PullOptions, logger: Logger) { config.endpoint = process.env['OPENFN_ENDPOINT']; } + const final_path = path.join( + options.projectPath ?? process.cwd(), + 'openfn.yaml' + ); + if (await fileExists(final_path)) { + return beta(options, logger); + } + logger.always( 'Downloading existing project state (as JSON) from the server.' ); diff --git a/packages/cli/src/util/file-exists.ts b/packages/cli/src/util/file-exists.ts new file mode 100644 index 000000000..97c6e61d9 --- /dev/null +++ b/packages/cli/src/util/file-exists.ts @@ -0,0 +1,10 @@ +import fs from 'fs/promises'; + +export async function fileExists(filePath: string) { + try { + const stats = await fs.stat(filePath); + return stats.isFile(); + } catch (error) { + return false; + } +} From 8bd6145a4609e20a453af35f91c9802f7f621d1f Mon Sep 17 00:00:00 2001 From: Farhan Yahaya Date: Fri, 20 Feb 2026 08:15:50 +0000 Subject: [PATCH 02/12] tests: file-exists --- packages/cli/src/deploy/handler.ts | 1 + packages/cli/src/pull/handler.ts | 1 + packages/cli/test/util/file-exists.test.ts | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 packages/cli/test/util/file-exists.test.ts diff --git a/packages/cli/src/deploy/handler.ts b/packages/cli/src/deploy/handler.ts index a3e943c23..50f753fa3 100644 --- a/packages/cli/src/deploy/handler.ts +++ b/packages/cli/src/deploy/handler.ts @@ -55,6 +55,7 @@ async function deployHandler( 'openfn.yaml' ); if (await fileExists(final_path)) { + logger.info('Switching to openfn project deploy'); return beta.handler(options, logger); } diff --git a/packages/cli/src/pull/handler.ts b/packages/cli/src/pull/handler.ts index 79c7b604e..9786bfbc8 100644 --- a/packages/cli/src/pull/handler.ts +++ b/packages/cli/src/pull/handler.ts @@ -37,6 +37,7 @@ async function pullHandler(options: PullOptions, logger: Logger) { 'openfn.yaml' ); if (await fileExists(final_path)) { + logger.info('Switching to openfn project pull'); return beta(options, logger); } diff --git a/packages/cli/test/util/file-exists.test.ts b/packages/cli/test/util/file-exists.test.ts new file mode 100644 index 000000000..a6c8ce7b4 --- /dev/null +++ b/packages/cli/test/util/file-exists.test.ts @@ -0,0 +1,22 @@ +import test from 'ava'; +import mockfs from 'mock-fs'; +import { fileExists } from '../../src/util/file-exists'; + +test.afterEach(() => { + mockfs.restore(); +}); + +test('returns true for an existing file', async (t) => { + mockfs({ './test.txt': 'content' }); + t.true(await fileExists('./test.txt')); +}); + +test('returns false for a non-existent path', async (t) => { + mockfs({}); + t.false(await fileExists('./nonexistent.txt')); +}); + +test('returns false for a directory', async (t) => { + mockfs({ './mydir': {} }); + t.false(await fileExists('./mydir')); +}); From 1503aa59232824eaf85c28ef8eae6bd226dbe139 Mon Sep 17 00:00:00 2001 From: Farhan Yahaya Date: Fri, 20 Feb 2026 09:08:43 +0000 Subject: [PATCH 03/12] feat: update --- packages/cli/src/deploy/handler.ts | 15 ++++++--------- packages/cli/src/projects/pull.ts | 1 + packages/cli/src/pull/handler.ts | 15 ++++++--------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/packages/cli/src/deploy/handler.ts b/packages/cli/src/deploy/handler.ts index 50f753fa3..0bed52e06 100644 --- a/packages/cli/src/deploy/handler.ts +++ b/packages/cli/src/deploy/handler.ts @@ -31,6 +31,12 @@ async function deployHandler( return beta.handler(options as any, logger); } + const final_path = path.join(process.cwd(), 'openfn.yaml'); + if (await fileExists(final_path)) { + logger.info('Switching to openfn project deploy'); + return beta.handler(options, logger); + } + try { const config = mergeOverrides(await getConfig(options.configPath), options); @@ -50,15 +56,6 @@ async function deployHandler( config.endpoint = process.env['OPENFN_ENDPOINT']; } - const final_path = path.join( - options.projectPath ?? process.cwd(), - 'openfn.yaml' - ); - if (await fileExists(final_path)) { - logger.info('Switching to openfn project deploy'); - return beta.handler(options, logger); - } - logger.debug('Deploying with config', config); logger.info(`Deploying`); diff --git a/packages/cli/src/projects/pull.ts b/packages/cli/src/projects/pull.ts index 6a3492561..d8046e6e2 100644 --- a/packages/cli/src/projects/pull.ts +++ b/packages/cli/src/projects/pull.ts @@ -61,6 +61,7 @@ export const command: yargs.CommandModule = { }; export async function handler(options: PullOptions, logger: Logger) { + options.workspace ??= process.cwd(); ensureProjectId(options, logger); await fetch(options, logger); diff --git a/packages/cli/src/pull/handler.ts b/packages/cli/src/pull/handler.ts index 9786bfbc8..402029cc2 100644 --- a/packages/cli/src/pull/handler.ts +++ b/packages/cli/src/pull/handler.ts @@ -19,6 +19,12 @@ async function pullHandler(options: PullOptions, logger: Logger) { return beta(options as any, logger); } + const final_path = path.join(process.cwd(), 'openfn.yaml'); + if (await fileExists(final_path)) { + logger.info('Switching to openfn project pull'); + return beta(options, logger); + } + try { const config = mergeOverrides(await getConfig(options.configPath), options); @@ -32,15 +38,6 @@ async function pullHandler(options: PullOptions, logger: Logger) { config.endpoint = process.env['OPENFN_ENDPOINT']; } - const final_path = path.join( - options.projectPath ?? process.cwd(), - 'openfn.yaml' - ); - if (await fileExists(final_path)) { - logger.info('Switching to openfn project pull'); - return beta(options, logger); - } - logger.always( 'Downloading existing project state (as JSON) from the server.' ); From d5c9ccf307439dd09b8bc64774fc8b2d82e8a60f Mon Sep 17 00:00:00 2001 From: Farhan Yahaya Date: Fri, 20 Feb 2026 11:04:08 +0000 Subject: [PATCH 04/12] feat: pass project id --- packages/cli/src/deploy/handler.ts | 12 ++++++------ packages/cli/src/pull/handler.ts | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/cli/src/deploy/handler.ts b/packages/cli/src/deploy/handler.ts index 0bed52e06..9935d49c9 100644 --- a/packages/cli/src/deploy/handler.ts +++ b/packages/cli/src/deploy/handler.ts @@ -31,15 +31,15 @@ async function deployHandler( return beta.handler(options as any, logger); } - const final_path = path.join(process.cwd(), 'openfn.yaml'); - if (await fileExists(final_path)) { - logger.info('Switching to openfn project deploy'); - return beta.handler(options, logger); - } - try { const config = mergeOverrides(await getConfig(options.configPath), options); + const final_path = path.join(process.cwd(), 'openfn.yaml'); + if (await fileExists(final_path)) { + logger.info('Switching to openfn project deploy'); + return beta.handler(options, logger); + } + logger.debug('Deploying with config', JSON.stringify(config, null, 2)); if (options.confirm === false) { diff --git a/packages/cli/src/pull/handler.ts b/packages/cli/src/pull/handler.ts index 402029cc2..a662602b4 100644 --- a/packages/cli/src/pull/handler.ts +++ b/packages/cli/src/pull/handler.ts @@ -19,15 +19,15 @@ async function pullHandler(options: PullOptions, logger: Logger) { return beta(options as any, logger); } - const final_path = path.join(process.cwd(), 'openfn.yaml'); - if (await fileExists(final_path)) { - logger.info('Switching to openfn project pull'); - return beta(options, logger); - } - try { const config = mergeOverrides(await getConfig(options.configPath), options); + const final_path = path.join(process.cwd(), 'openfn.yaml'); + if (await fileExists(final_path)) { + logger.info('Switching to openfn project pull'); + return beta({ ...options, project: options.projectId }, logger); + } + if (process.env['OPENFN_API_KEY']) { logger.info('Using OPENFN_API_KEY environment variable'); config.apiKey = process.env['OPENFN_API_KEY']; From e091e6d515bf3a72dba990f95299edda1aeec5b9 Mon Sep 17 00:00:00 2001 From: Farhan Yahaya Date: Fri, 20 Feb 2026 11:04:18 +0000 Subject: [PATCH 05/12] tests: add test for redirect --- packages/cli/test/pull/handler.test.ts | 38 ++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 packages/cli/test/pull/handler.test.ts diff --git a/packages/cli/test/pull/handler.test.ts b/packages/cli/test/pull/handler.test.ts new file mode 100644 index 000000000..939c871f2 --- /dev/null +++ b/packages/cli/test/pull/handler.test.ts @@ -0,0 +1,38 @@ +import test from 'ava'; +import mockfs from 'mock-fs'; +import { createMockLogger } from '@openfn/logger'; +import pullHandler from '../../src/pull/handler'; +import { PullOptions } from '../../src/pull/command'; + +test.beforeEach(() => { + mockfs.restore(); +}); + +test.afterEach(() => { + mockfs.restore(); +}); + +const options: PullOptions = { + beta: false, + command: 'pull', + projectPath: './project.yaml', + configPath: './config.json', + projectId: 'abc-123', + confirm: false, + snapshots: [], +}; + +test.serial( + 'redirects to beta handler when openfn.yaml exists in cwd', + async (t) => { + const logger = createMockLogger('', { level: 'debug' }); + mockfs({ + ['./config.json']: `{"apiKey": "123"}`, + ['./openfn.yaml']: '', + }); + + await t.throwsAsync(() => pullHandler(options, logger)); + + t.truthy(logger._find('info', /Switching to openfn project pull/)); + } +); From 87470dd0b24f097f3e55cca663034a1449cad9ac Mon Sep 17 00:00:00 2001 From: Farhan Yahaya Date: Fri, 20 Feb 2026 12:27:11 +0000 Subject: [PATCH 06/12] feat: add workspace to old pull --- packages/cli/src/pull/command.ts | 4 +++- packages/cli/src/pull/handler.ts | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/pull/command.ts b/packages/cli/src/pull/command.ts index ba6dd6620..314164623 100644 --- a/packages/cli/src/pull/command.ts +++ b/packages/cli/src/pull/command.ts @@ -1,12 +1,13 @@ import yargs from 'yargs'; import { build, ensure, override } from '../util/command-builders'; import { Opts } from '../options'; +import { Opts as POpts } from '../projects/options'; import * as o from '../options'; import * as po from '../projects/options'; export type PullOptions = Required< Pick< - Opts, + Opts & POpts, | 'beta' | 'command' | 'log' @@ -17,6 +18,7 @@ export type PullOptions = Required< | 'projectId' | 'confirm' | 'snapshots' + | 'workspace' > >; diff --git a/packages/cli/src/pull/handler.ts b/packages/cli/src/pull/handler.ts index a662602b4..293535217 100644 --- a/packages/cli/src/pull/handler.ts +++ b/packages/cli/src/pull/handler.ts @@ -22,7 +22,10 @@ async function pullHandler(options: PullOptions, logger: Logger) { try { const config = mergeOverrides(await getConfig(options.configPath), options); - const final_path = path.join(process.cwd(), 'openfn.yaml'); + const final_path = path.join( + options.workspace || process.cwd(), + 'openfn.yaml' + ); if (await fileExists(final_path)) { logger.info('Switching to openfn project pull'); return beta({ ...options, project: options.projectId }, logger); From f1b13997b959c04a9e54ccc99cffe1a142aca8bc Mon Sep 17 00:00:00 2001 From: Farhan Yahaya Date: Fri, 20 Feb 2026 12:36:49 +0000 Subject: [PATCH 07/12] feat: support workspace in deploy --- packages/cli/src/deploy/command.ts | 4 +++- packages/cli/src/deploy/handler.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/deploy/command.ts b/packages/cli/src/deploy/command.ts index 79ed15cc4..6b144f8ee 100644 --- a/packages/cli/src/deploy/command.ts +++ b/packages/cli/src/deploy/command.ts @@ -1,12 +1,13 @@ import yargs from 'yargs'; import { build, ensure, override } from '../util/command-builders'; import { Opts } from '../options'; +import { Opts as POpts } from '../projects/options'; import * as o from '../options'; import * as o2 from '../projects/options'; export type DeployOptions = Required< Pick< - Opts, + Opts & POpts, | 'beta' | 'command' | 'configPath' @@ -15,6 +16,7 @@ export type DeployOptions = Required< | 'logJson' | 'projectPath' | 'statePath' + | 'workspace' > >; diff --git a/packages/cli/src/deploy/handler.ts b/packages/cli/src/deploy/handler.ts index 9935d49c9..87e293506 100644 --- a/packages/cli/src/deploy/handler.ts +++ b/packages/cli/src/deploy/handler.ts @@ -34,7 +34,7 @@ async function deployHandler( try { const config = mergeOverrides(await getConfig(options.configPath), options); - const final_path = path.join(process.cwd(), 'openfn.yaml'); + const final_path = path.join(options.workspace || process.cwd(), 'openfn.yaml'); if (await fileExists(final_path)) { logger.info('Switching to openfn project deploy'); return beta.handler(options, logger); From 71f7c4c41db86e0c816bade35b54930a74bae960 Mon Sep 17 00:00:00 2001 From: Farhan Yahaya Date: Mon, 23 Feb 2026 14:48:17 +0000 Subject: [PATCH 08/12] fix: path to spec & state file with workspace --- packages/cli/src/deploy/handler.ts | 10 +++++++--- packages/cli/src/pull/handler.ts | 5 ++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/deploy/handler.ts b/packages/cli/src/deploy/handler.ts index 87e293506..16d7dcf7e 100644 --- a/packages/cli/src/deploy/handler.ts +++ b/packages/cli/src/deploy/handler.ts @@ -84,13 +84,17 @@ function mergeOverrides( config: DeployConfig, options: DeployOptions ): DeployConfig { + const workspace = options.workspace || process.env['OPENFN_WORKSPACE'] || process.cwd(); + const resolveRelative = (p: string) => path.isAbsolute(p) ? p : path.join(workspace, p); + const specPath = pickFirst(options.projectPath, config.specPath); + const statePath = pickFirst(options.statePath, config.statePath); return { ...config, apiKey: pickFirst(process.env['OPENFN_API_KEY'], config.apiKey), endpoint: pickFirst(process.env['OPENFN_ENDPOINT'], config.endpoint), - statePath: pickFirst(options.statePath, config.statePath), - specPath: pickFirst(options.projectPath, config.specPath), - configPath: options.configPath, + statePath: resolveRelative(statePath), + specPath: resolveRelative(specPath), + configPath: resolveRelative(options.configPath), requireConfirmation: pickFirst(options.confirm, config.requireConfirmation), }; } diff --git a/packages/cli/src/pull/handler.ts b/packages/cli/src/pull/handler.ts index 293535217..0623deaf0 100644 --- a/packages/cli/src/pull/handler.ts +++ b/packages/cli/src/pull/handler.ts @@ -137,11 +137,14 @@ function mergeOverrides( config: DeployConfig, options: PullOptions ): DeployConfig { + const workspace = options.workspace || process.env['OPENFN_WORKSPACE'] || process.cwd(); return { ...config, apiKey: pickFirst(process.env['OPENFN_API_KEY'], config.apiKey), endpoint: pickFirst(process.env['OPENFN_ENDPOINT'], config.endpoint), - configPath: options.configPath, + configPath: path.isAbsolute(options.configPath) ? options.configPath : path.join(workspace, options.configPath), + specPath: path.isAbsolute(config.specPath) ? config.specPath : path.join(workspace, config.specPath), + statePath: path.isAbsolute(config.statePath) ? config.statePath : path.join(workspace, config.statePath), requireConfirmation: pickFirst(options.confirm, config.requireConfirmation), }; } From 21558daa30216686bd0b6127797b1f6272077232 Mon Sep 17 00:00:00 2001 From: Farhan Yahaya Date: Tue, 24 Feb 2026 07:10:00 +0000 Subject: [PATCH 09/12] chore: fix formatting --- packages/cli/src/deploy/handler.ts | 11 ++++++++--- packages/cli/src/pull/handler.ts | 15 +++++++++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/cli/src/deploy/handler.ts b/packages/cli/src/deploy/handler.ts index 16d7dcf7e..cec180bd6 100644 --- a/packages/cli/src/deploy/handler.ts +++ b/packages/cli/src/deploy/handler.ts @@ -34,7 +34,10 @@ async function deployHandler( try { const config = mergeOverrides(await getConfig(options.configPath), options); - const final_path = path.join(options.workspace || process.cwd(), 'openfn.yaml'); + const final_path = path.join( + options.workspace || process.cwd(), + 'openfn.yaml' + ); if (await fileExists(final_path)) { logger.info('Switching to openfn project deploy'); return beta.handler(options, logger); @@ -84,8 +87,10 @@ function mergeOverrides( config: DeployConfig, options: DeployOptions ): DeployConfig { - const workspace = options.workspace || process.env['OPENFN_WORKSPACE'] || process.cwd(); - const resolveRelative = (p: string) => path.isAbsolute(p) ? p : path.join(workspace, p); + const workspace = + options.workspace || process.env['OPENFN_WORKSPACE'] || process.cwd(); + const resolveRelative = (p: string) => + path.isAbsolute(p) ? p : path.join(workspace, p); const specPath = pickFirst(options.projectPath, config.specPath); const statePath = pickFirst(options.statePath, config.statePath); return { diff --git a/packages/cli/src/pull/handler.ts b/packages/cli/src/pull/handler.ts index 0623deaf0..9087e4f13 100644 --- a/packages/cli/src/pull/handler.ts +++ b/packages/cli/src/pull/handler.ts @@ -137,14 +137,21 @@ function mergeOverrides( config: DeployConfig, options: PullOptions ): DeployConfig { - const workspace = options.workspace || process.env['OPENFN_WORKSPACE'] || process.cwd(); + const workspace = + options.workspace || process.env['OPENFN_WORKSPACE'] || process.cwd(); return { ...config, apiKey: pickFirst(process.env['OPENFN_API_KEY'], config.apiKey), endpoint: pickFirst(process.env['OPENFN_ENDPOINT'], config.endpoint), - configPath: path.isAbsolute(options.configPath) ? options.configPath : path.join(workspace, options.configPath), - specPath: path.isAbsolute(config.specPath) ? config.specPath : path.join(workspace, config.specPath), - statePath: path.isAbsolute(config.statePath) ? config.statePath : path.join(workspace, config.statePath), + configPath: path.isAbsolute(options.configPath) + ? options.configPath + : path.join(workspace, options.configPath), + specPath: path.isAbsolute(config.specPath) + ? config.specPath + : path.join(workspace, config.specPath), + statePath: path.isAbsolute(config.statePath) + ? config.statePath + : path.join(workspace, config.statePath), requireConfirmation: pickFirst(options.confirm, config.requireConfirmation), }; } From 83e8fcd94c7ac801bc799b0c03b4b994ebf91eff Mon Sep 17 00:00:00 2001 From: Farhan Yahaya Date: Tue, 24 Feb 2026 16:24:46 +0000 Subject: [PATCH 10/12] chore: handle comments --- packages/cli/src/deploy/handler.ts | 13 +++++++------ packages/cli/src/pull/handler.ts | 11 ++++++----- packages/cli/test/pull/handler.test.ts | 7 ++++++- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/packages/cli/src/deploy/handler.ts b/packages/cli/src/deploy/handler.ts index cec180bd6..4e834a0fb 100644 --- a/packages/cli/src/deploy/handler.ts +++ b/packages/cli/src/deploy/handler.ts @@ -34,13 +34,15 @@ async function deployHandler( try { const config = mergeOverrides(await getConfig(options.configPath), options); - const final_path = path.join( + const v2ConfigPath = path.join( options.workspace || process.cwd(), 'openfn.yaml' ); - if (await fileExists(final_path)) { - logger.info('Switching to openfn project deploy'); - return beta.handler(options, logger); + if (await fileExists(v2ConfigPath)) { + logger.always( + 'Detected openfn.yaml file - switching to v2 deploy (openfn project deploy)' + ); + return beta.handler({ ...options, force: true }, logger); } logger.debug('Deploying with config', JSON.stringify(config, null, 2)); @@ -87,8 +89,7 @@ function mergeOverrides( config: DeployConfig, options: DeployOptions ): DeployConfig { - const workspace = - options.workspace || process.env['OPENFN_WORKSPACE'] || process.cwd(); + const workspace = options.workspace || process.cwd(); const resolveRelative = (p: string) => path.isAbsolute(p) ? p : path.join(workspace, p); const specPath = pickFirst(options.projectPath, config.specPath); diff --git a/packages/cli/src/pull/handler.ts b/packages/cli/src/pull/handler.ts index 9087e4f13..45fd47ec7 100644 --- a/packages/cli/src/pull/handler.ts +++ b/packages/cli/src/pull/handler.ts @@ -22,12 +22,14 @@ async function pullHandler(options: PullOptions, logger: Logger) { try { const config = mergeOverrides(await getConfig(options.configPath), options); - const final_path = path.join( + const v2ConfigPath = path.join( options.workspace || process.cwd(), 'openfn.yaml' ); - if (await fileExists(final_path)) { - logger.info('Switching to openfn project pull'); + if (await fileExists(v2ConfigPath)) { + logger.info( + 'Detected openfn.yaml file - switching to v2 pull (openfn project pull)' + ); return beta({ ...options, project: options.projectId }, logger); } @@ -137,8 +139,7 @@ function mergeOverrides( config: DeployConfig, options: PullOptions ): DeployConfig { - const workspace = - options.workspace || process.env['OPENFN_WORKSPACE'] || process.cwd(); + const workspace = options.workspace || process.cwd(); return { ...config, apiKey: pickFirst(process.env['OPENFN_API_KEY'], config.apiKey), diff --git a/packages/cli/test/pull/handler.test.ts b/packages/cli/test/pull/handler.test.ts index 939c871f2..58cb99620 100644 --- a/packages/cli/test/pull/handler.test.ts +++ b/packages/cli/test/pull/handler.test.ts @@ -33,6 +33,11 @@ test.serial( await t.throwsAsync(() => pullHandler(options, logger)); - t.truthy(logger._find('info', /Switching to openfn project pull/)); + t.truthy( + logger._find( + 'info', + /Detected openfn.yaml file - switching to v2 pull (openfn project pull)/ + ) + ); } ); From c62caac49bfaa9b42911ef9840664f802191586b Mon Sep 17 00:00:00 2001 From: Joe Clark Date: Thu, 26 Feb 2026 14:42:45 +0000 Subject: [PATCH 11/12] tweaks --- packages/cli/src/projects/pull.ts | 1 + packages/cli/src/pull/handler.ts | 7 +++++-- packages/cli/test/pull/handler.test.ts | 7 +------ 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/cli/src/projects/pull.ts b/packages/cli/src/projects/pull.ts index d8046e6e2..1df4af557 100644 --- a/packages/cli/src/projects/pull.ts +++ b/packages/cli/src/projects/pull.ts @@ -23,6 +23,7 @@ export type PullOptions = Pick< | 'project' | 'confirm' | 'snapshots' + | 'force' >; const options = [ diff --git a/packages/cli/src/pull/handler.ts b/packages/cli/src/pull/handler.ts index 45fd47ec7..2981ce5ed 100644 --- a/packages/cli/src/pull/handler.ts +++ b/packages/cli/src/pull/handler.ts @@ -27,10 +27,13 @@ async function pullHandler(options: PullOptions, logger: Logger) { 'openfn.yaml' ); if (await fileExists(v2ConfigPath)) { - logger.info( + logger.always( 'Detected openfn.yaml file - switching to v2 pull (openfn project pull)' ); - return beta({ ...options, project: options.projectId }, logger); + return beta( + { ...options, project: options.projectId, force: true }, + logger + ); } if (process.env['OPENFN_API_KEY']) { diff --git a/packages/cli/test/pull/handler.test.ts b/packages/cli/test/pull/handler.test.ts index 58cb99620..3ef838dff 100644 --- a/packages/cli/test/pull/handler.test.ts +++ b/packages/cli/test/pull/handler.test.ts @@ -33,11 +33,6 @@ test.serial( await t.throwsAsync(() => pullHandler(options, logger)); - t.truthy( - logger._find( - 'info', - /Detected openfn.yaml file - switching to v2 pull (openfn project pull)/ - ) - ); + t.truthy(logger._find('always', /Detected openfn.yaml file/i)); } ); From cbc018c40e0fd319ef51c79abb6bfca9930ad2e9 Mon Sep 17 00:00:00 2001 From: Joe Clark Date: Thu, 26 Feb 2026 14:56:42 +0000 Subject: [PATCH 12/12] changeset --- .changeset/vast-weeks-tap.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .changeset/vast-weeks-tap.md diff --git a/.changeset/vast-weeks-tap.md b/.changeset/vast-weeks-tap.md new file mode 100644 index 000000000..953c4560a --- /dev/null +++ b/.changeset/vast-weeks-tap.md @@ -0,0 +1,13 @@ +--- +'@openfn/cli': minor +--- + +Support github sync with new `project` commands + +GitHub Sync is currently designed with a pair of actions which trigger the legacy `openfn deploy` and `openfn pull` commands. + +This update adds support for the `openfn.yaml` file to the commands: so if you run `openfn project pull` in a github synced repo, the repo goes into v2 mode. The legacy deploy and pull commands will "redirect" to v2. You should leave the legacy `config.json` file, but state.json and spec.yaml files can be removed. + +Initaliasing GitHub sync from the app will continue to use the legacy file structure for the initial commit. If you want to switch to v2, either create an empty openfn.yaml and trigger a sync, or locally run `openfn project pull` and commit changes. + +Be aware that v2 sync only supports a single `openfn.yaml` and `workflows` folder at a time - so a sync which pulls from multiple connected apps will not work well. It should however be safe to push changes to multiple apps.