diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 32d0a458c..c7cd59a05 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,16 @@ # @openfn/cli +## 1.6.0 + +### Minor Changes + +- 960f293: Add snapshots option to cli pull command + +### Patch Changes + +- Updated dependencies [960f293] + - @openfn/deploy@0.5.0 + ## 1.5.0 ### Minor Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index a6b624c6f..b070576fd 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@openfn/cli", - "version": "1.5.0", + "version": "1.6.0", "description": "CLI devtools for the openfn toolchain.", "engines": { "node": ">=18", diff --git a/packages/cli/src/options.ts b/packages/cli/src/options.ts index 8976a65bc..3082082b8 100644 --- a/packages/cli/src/options.ts +++ b/packages/cli/src/options.ts @@ -46,6 +46,7 @@ export type Opts = { repoDir?: string; sanitize: 'none' | 'remove' | 'summarize' | 'obfuscate'; skipAdaptorValidation?: boolean; + snapshots?: string[]; specifier?: string; // docgen start?: string; // workflow start step statePath?: string; @@ -402,6 +403,14 @@ export const skipAdaptorValidation: CLIOption = { }, }; +export const snapshots: CLIOption = { + name: 'snapshots', + yargs: { + description: 'List of snapshot ids to pull', + array: true, + }, +}; + export const statePath: CLIOption = { name: 'state-path', yargs: { diff --git a/packages/cli/src/pull/command.ts b/packages/cli/src/pull/command.ts index 6697783ff..e714aea7f 100644 --- a/packages/cli/src/pull/command.ts +++ b/packages/cli/src/pull/command.ts @@ -14,10 +14,18 @@ export type PullOptions = Required< | 'configPath' | 'projectId' | 'confirm' + | 'snapshots' > >; -const options = [o.statePath, o.projectPath, o.configPath, o.log, o.logJson]; +const options = [ + o.statePath, + o.projectPath, + o.configPath, + o.log, + o.logJson, + o.snapshots, +]; const pullCommand: yargs.CommandModule = { command: 'pull [projectId]', diff --git a/packages/cli/src/pull/handler.ts b/packages/cli/src/pull/handler.ts index d6a42812f..d8cf2fc8b 100644 --- a/packages/cli/src/pull/handler.ts +++ b/packages/cli/src/pull/handler.ts @@ -29,7 +29,11 @@ async function pullHandler(options: PullOptions, logger: Logger) { ); // Get the project.json from Lightning - const { data: project } = await getProject(config, options.projectId); + const { data: project } = await getProject( + config, + options.projectId, + options.snapshots + ); if (!project) { logger.error('ERROR: Project not found.'); diff --git a/packages/deploy/CHANGELOG.md b/packages/deploy/CHANGELOG.md index 7c148a157..340d3d231 100644 --- a/packages/deploy/CHANGELOG.md +++ b/packages/deploy/CHANGELOG.md @@ -1,5 +1,11 @@ # @openfn/deploy +## 0.5.0 + +### Minor Changes + +- 960f293: Add snapshots option to cli pull command + ## 0.4.7 ### Patch Changes diff --git a/packages/deploy/package.json b/packages/deploy/package.json index 82f54aa84..b44df532c 100644 --- a/packages/deploy/package.json +++ b/packages/deploy/package.json @@ -1,6 +1,6 @@ { "name": "@openfn/deploy", - "version": "0.4.7", + "version": "0.5.0", "description": "Deploy projects to Lightning instances", "type": "module", "exports": { diff --git a/packages/deploy/src/client.ts b/packages/deploy/src/client.ts index 28fb9388f..5ee4fa485 100644 --- a/packages/deploy/src/client.ts +++ b/packages/deploy/src/client.ts @@ -1,14 +1,25 @@ import { DeployConfig, ProjectPayload } from './types'; import { DeployError } from './deployError'; -const getLightningUrl = (config: DeployConfig, path: string = '') => - new URL(`/api/provision/${path}`, config.endpoint); +export const getLightningUrl = ( + config: DeployConfig, + path: string = '', + snapshots?: string[] +) => { + const params = new URLSearchParams(); + snapshots?.forEach((snapshot) => params.append('snapshots[]', snapshot)); + return new URL( + `/api/provision/${path}?${params.toString()}`, + config.endpoint + ); +}; export async function getProject( config: DeployConfig, - projectId: string + projectId: string, + snapshots?: string[] ): Promise<{ data: ProjectPayload | null }> { - const url = getLightningUrl(config, projectId); + const url = getLightningUrl(config, projectId, snapshots); console.log(`Checking ${url} for existing project.`); try { diff --git a/packages/deploy/test/index.test.ts b/packages/deploy/test/index.test.ts index 83b1b7923..cbd992aaf 100644 --- a/packages/deploy/test/index.test.ts +++ b/packages/deploy/test/index.test.ts @@ -1,6 +1,8 @@ import { render } from '@inquirer/testing'; import { input } from '@inquirer/prompts'; import test from 'ava'; +import { DeployConfig } from '../src/types'; +import { getLightningUrl } from '../src/client'; test('renders a confirmation', async (t) => { const { answer, events, getScreen } = await render(input, { @@ -14,3 +16,37 @@ test('renders a confirmation', async (t) => { t.is(await answer, 'John'); }); + +test('getLightningUrl adds snapshots correctly to the URL', async (t) => { + const config: DeployConfig = { + endpoint: 'http://localhost', + apiKey: 'test-api-key', + specPath: './project.yaml', + statePath: './state.json', + requireConfirmation: false, + dryRun: false, + }; + + const projectId = 'test-project'; + const snapshots = ['snapshot1', 'snapshot2']; + + const expectedUrl = + 'http://localhost/api/provision/test-project?snapshots%5B%5D=snapshot1&snapshots%5B%5D=snapshot2'; + t.is(getLightningUrl(config, projectId, snapshots).toString(), expectedUrl); +}); + +test('getLightningUrl returns the correct URL when no snapshot is provided', async (t) => { + const config: DeployConfig = { + endpoint: 'http://localhost', + apiKey: 'test-api-key', + specPath: './project.yaml', + statePath: './state.json', + requireConfirmation: false, + dryRun: false, + }; + + const projectId = 'test-project'; + + const expectedUrl = 'http://localhost/api/provision/test-project?'; + t.is(getLightningUrl(config, projectId).toString(), expectedUrl); +});