Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/honest-aliens-sleep.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@openfn/cli': patch
---

Fix endpoint tracing on deploy command
2 changes: 2 additions & 0 deletions packages/cli/src/deploy/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import * as o2 from '../projects/options';
export type DeployOptions = Required<
Pick<
Opts & POpts,
| 'endpoint'
| 'apiKey'
| 'beta'
| 'command'
| 'configPath'
Expand Down
28 changes: 16 additions & 12 deletions packages/cli/src/deploy/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<F extends (...args: any) => any>(
options: DeployOptions,
logger: Logger,
deployFn: F
deployFn: F,
betaHandler?: BetaHandlerFn
): Promise<ReturnType<typeof deployFn>>;

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 {
Expand All @@ -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) {
Expand Down Expand Up @@ -110,24 +114,24 @@ 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.'
);

// 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
);
Expand Down
3 changes: 1 addition & 2 deletions packages/cli/src/projects/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
1 change: 0 additions & 1 deletion packages/cli/src/projects/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
85 changes: 85 additions & 0 deletions packages/cli/test/deploy/deploy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down