diff --git a/.changeset/honest-aliens-sleep.md b/.changeset/honest-aliens-sleep.md new file mode 100644 index 000000000..6b6e7b87c --- /dev/null +++ b/.changeset/honest-aliens-sleep.md @@ -0,0 +1,5 @@ +--- +'@openfn/cli': patch +--- + +Fix endpoint tracing on deploy command diff --git a/packages/cli/src/deploy/command.ts b/packages/cli/src/deploy/command.ts index 6b144f8ee..f6e32d1f6 100644 --- a/packages/cli/src/deploy/command.ts +++ b/packages/cli/src/deploy/command.ts @@ -8,6 +8,8 @@ import * as o2 from '../projects/options'; export type DeployOptions = Required< Pick< Opts & POpts, + | 'endpoint' + | 'apiKey' | 'beta' | 'command' | 'configPath' diff --git a/packages/cli/src/deploy/handler.ts b/packages/cli/src/deploy/handler.ts index b448a6210..13b0d7fd7 100644 --- a/packages/cli/src/deploy/handler.ts +++ b/packages/cli/src/deploy/handler.ts @@ -14,23 +14,27 @@ import { yamlToJson } from '@openfn/project'; import fs from 'node:fs/promises'; export type DeployFn = typeof deploy; +export type BetaHandlerFn = typeof beta.handler; const actualDeploy: DeployFn = deploy; +const actualBetaHandler: BetaHandlerFn = beta.handler; -// Flexible `deployFn` interface for testing. +// Flexible `deployFn` / `betaHandler` interfaces for testing. async function deployHandler any>( options: DeployOptions, logger: Logger, - deployFn: F + deployFn: F, + betaHandler?: BetaHandlerFn ): Promise>; async function deployHandler( options: DeployOptions, logger: Logger, - deployFn = actualDeploy + deployFn = actualDeploy, + betaHandler: BetaHandlerFn = actualBetaHandler ) { if (options.beta) { - return beta.handler(options as any, logger); + return betaHandler(options as any, logger); } try { @@ -41,7 +45,7 @@ async function deployHandler( 'openfn.yaml' ); if (!process.env.PREFER_LEGACY_SYNC && (await fileExists(v2ConfigPath))) { - return redirectTov2(v2ConfigPath, options, config, logger); + return redirectTov2(v2ConfigPath, options, config, logger, betaHandler); } if (options.confirm === false) { @@ -110,7 +114,8 @@ const redirectTov2 = async ( v2ConfigPath: string, options: DeployOptions, config: DeployConfig, - logger: Logger + logger: Logger, + betaHandler: BetaHandlerFn = actualBetaHandler ) => { logger.always( 'Detected openfn.yaml file - switching to v2 deploy (openfn project deploy). Set PREFER_LEGACY_SYNC to disable this.' @@ -118,16 +123,15 @@ const redirectTov2 = async ( // default endpoint to one from openfn.yaml const v2config = yamlToJson(await fs.readFile(v2ConfigPath, 'utf-8')); - if (!config.endpoint && v2config?.project?.endpoint) { - config.endpoint = v2config.project.endpoint; - } + const endpoint = + options.endpoint ?? v2config?.project?.endpoint ?? config.endpoint; - return beta.handler( + return betaHandler( { ...options, force: true, - endpoint: config.endpoint, - apiKey: config.apiKey ?? undefined, + endpoint, + apiKey: options.apiKey ?? config.apiKey ?? undefined, }, logger ); diff --git a/packages/cli/src/projects/deploy.ts b/packages/cli/src/projects/deploy.ts index 69f17d6aa..11185bee2 100644 --- a/packages/cli/src/projects/deploy.ts +++ b/packages/cli/src/projects/deploy.ts @@ -148,7 +148,6 @@ const syncProjects = async ( // TODO should we prefer endpoint over alias? // maybe if it's explicitly passed? const endpoint = trackedProject.openfn?.endpoint ?? config.endpoint; - const { data } = await fetchProject( endpoint, config.apiKey, @@ -162,7 +161,7 @@ const syncProjects = async ( logger.info('Downloaded latest version of project at ', endpoint); } catch (e) { - console.log(e); + logger.error(e); throw e; // If fetch failed because of compatiblity with the local project, what do we do? // Well, actually I don't think I want this fetch to write to disk yet diff --git a/packages/cli/src/projects/util.ts b/packages/cli/src/projects/util.ts index 7a9185585..abe1f7e7b 100644 --- a/packages/cli/src/projects/util.ts +++ b/packages/cli/src/projects/util.ts @@ -121,7 +121,6 @@ export async function fetchProject( ): Promise<{ data: Provisioner.Project | null }> { const url = getLightningUrl(endpoint, projectId, snapshots); logger?.info(`Checking ${url} for existing project`); - try { const response = await fetch(url, { headers: { diff --git a/packages/cli/test/deploy/deploy.test.ts b/packages/cli/test/deploy/deploy.test.ts index b58bc25a9..0e9ea411d 100644 --- a/packages/cli/test/deploy/deploy.test.ts +++ b/packages/cli/test/deploy/deploy.test.ts @@ -88,6 +88,91 @@ test.serial('sets the exit code to 1', async (t) => { process.exitCode = origExitCode; }); +test.serial( + 'redirects to beta handler when openfn.yaml exists in cwd', + async (t) => { + t.plan(3); + mockfs({ + ['./config.json']: `{"apiKey": "123"}`, + ['./project.yaml']: `{"apiKey": "123"}`, + ['./openfn.yaml']: 'project:\n endpoint: https://from-yaml.org', + }); + + await deployHandler(options, logger, mockDeploy, async (args: any) => { + t.is(args.force, true); + t.is(args.endpoint, 'https://from-yaml.org'); + t.truthy(logger._find('always', /Detected openfn.yaml file/i)); + }); + } +); + +test.serial('does not redirect when PREFER_LEGACY_SYNC is set', async (t) => { + t.plan(1); + mockfs({ + ['./config.json']: `{"apiKey": "123", "endpoint": "https://api.example.com"}`, + ['./project.yaml']: `{"apiKey": "123"}`, + ['./openfn.yaml']: 'project:\n endpoint: https://from-yaml.org', + }); + process.env.PREFER_LEGACY_SYNC = '1'; + + await deployHandler(options, logger, mockDeploy, async (args: any) => { + t.fail('called beta handler'); + }); + + delete process.env.PREFER_LEGACY_SYNC; + t.pass(); +}); + +test.serial('CLI endpoint preferred over openfn.yaml endpoint', async (t) => { + t.plan(1); + mockfs({ + ['./config.json']: `{"apiKey": "123"}`, + ['./project.yaml']: `{"apiKey": "123"}`, + ['./openfn.yaml']: 'project:\n endpoint: https://from-yaml.org', + }); + + await deployHandler( + { ...options, endpoint: 'https://from-cli.org' } as any, + logger, + mockDeploy, + async (args: any) => { + t.is(args.endpoint, 'https://from-cli.org'); + } + ); +}); + +test.serial( + 'openfn.yaml endpoint preferred over config.json endpoint', + async (t) => { + mockfs({ + ['./config.json']: `{"apiKey": "123", "endpoint": "https://from-config.org"}`, + ['./project.yaml']: `{"apiKey": "123"}`, + ['./openfn.yaml']: 'project:\n endpoint: https://from-yaml.org', + }); + + await deployHandler(options, logger, mockDeploy, async (args: any) => { + t.is(args.endpoint, 'https://from-yaml.org'); + }); + } +); + +test.serial('CLI apiKey preferred over config.json apiKey', async (t) => { + mockfs({ + ['./config.json']: `{"apiKey": "from-config"}`, + ['./project.yaml']: `{"apiKey": "from-config"}`, + ['./openfn.yaml']: 'project:\n endpoint: https://from-yaml.org', + }); + + await deployHandler( + { ...options, apiKey: 'from-cli' } as any, + logger, + mockDeploy, + async (args: any) => { + t.is(args.apiKey, 'from-cli'); + } + ); +}); + test.serial('catches DeployErrors', async (t) => { const origExitCode = process.exitCode;