Skip to content

Add deploy query limit option to CLI #2419

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 30, 2024
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
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@
"eslint-plugin-header": "^3.1.1",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jest": "^27.2.3",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-sort-destructure-keys": "^1.4.0",
"husky": "^7.0.4",
"jest": "^29.5.0",
"lint-staged": "^12.3.3",
"node-fetch": "2.6.7",
"prettier": "^2.5.1",
"prettier": "^3.2.5",
"pretty-quick": "^3.1.3",
"regenerator-runtime": "^0.13.9",
"ts-jest": "^29.1.1",
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- `--queryLimit` flag to deploy command for query service (#2419)

## [4.10.1] - 2024-05-27
### Fixed
Expand Down
13 changes: 7 additions & 6 deletions packages/cli/src/commands/deployment/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ import {addV, checkToken, promptWithDefaultValues, valueOrPrompt} from '../../ut
export default class Deploy extends Command {
static description = 'Deployment to hosted service';

static flags = Object.assign(DefaultDeployFlags, {
static flags = {
...DefaultDeployFlags,
ipfsCID: Flags.string({description: 'Enter IPFS CID'}),
endpoint: Flags.string({description: 'Enter endpoint', required: true}),
});
};

async run(): Promise<void> {
const {flags} = await this.parse(Deploy);
Expand Down Expand Up @@ -119,12 +120,12 @@ export default class Deploy extends Command {

await executeProjectDeployment({
log: this.log.bind(this),
authToken: authToken,
chains: chains,
flags: flags,
authToken,
chains,
flags,
ipfsCID: flags.ipfsCID,
org: flags.org,
projectInfo: flags.projectInfo,
projectInfo,
projectName: flags.projectName,
queryVersion: flags.queryVersion,
});
Expand Down
13 changes: 7 additions & 6 deletions packages/cli/src/commands/multi-chain/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ import {addV, checkToken, promptWithDefaultValues, resolveToAbsolutePath, valueO
export default class MultiChainDeploy extends Command {
static description = 'Multi-chain deployment to hosted service';

static flags = Object.assign(DefaultDeployFlags, {
static flags = {
...DefaultDeployFlags,
location: Flags.string({char: 'f', description: 'from project folder or specify manifest file', required: true}),
ipfs: Flags.string({description: 'IPFS gateway endpoint', required: false}),
});
};

async run(): Promise<void> {
const {flags} = await this.parse(MultiChainDeploy);
Expand Down Expand Up @@ -182,12 +183,12 @@ export default class MultiChainDeploy extends Command {

await executeProjectDeployment({
log: this.log.bind(this),
authToken: authToken,
chains: chains,
flags: flags,
authToken,
chains,
flags,
ipfsCID: ipfsCID,
org: flags.org,
projectInfo: projectInfo,
projectInfo,
projectName: flags.projectName,
queryVersion: flags.queryVersion,
});
Expand Down
127 changes: 63 additions & 64 deletions packages/cli/src/controller/deploy-controller.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors
// SPDX-License-Identifier: GPL-3.0

import {Flags} from "@oclif/core";
import {FlagInput} from "@oclif/core/lib/interfaces/parser";
import {Flags} from '@oclif/core';
import {FlagInput} from '@oclif/core/lib/interfaces/parser';
import axios, {Axios} from 'axios';
import chalk from "chalk";
import {BASE_PROJECT_URL, DEFAULT_DEPLOYMENT_TYPE, ROOT_API_URL_PROD} from "../constants";
import chalk from 'chalk';
import {BASE_PROJECT_URL, DEFAULT_DEPLOYMENT_TYPE, ROOT_API_URL_PROD} from '../constants';
import {
DeploymentDataType,
ProjectDataType,
Expand All @@ -16,7 +16,7 @@ import {
ProjectDeploymentInterface,
GenerateDeploymentChainInterface,
DeploymentFlagsInterface,
MultichainDataFieldType
MultichainDataFieldType,
} from '../types';
import {buildProjectKey, errorHandle} from '../utils';

Expand Down Expand Up @@ -103,7 +103,7 @@ export async function deploymentStatus(
url: string
): Promise<string> {
try {
const res = await getAxiosInstance(url, authToken).get<{ status: string }>(
const res = await getAxiosInstance(url, authToken).get<{status: string}>(
`subqueries/${buildProjectKey(org, projectName)}/deployments/${deployID}/status`
);
return `${res.data.status}`;
Expand Down Expand Up @@ -161,7 +161,7 @@ export async function ipfsCID_validate(cid: string, authToken: string, url: stri
const res = await getAxiosInstance(url, authToken).post<ValidateDataType>(`ipfs/deployment-id/${cid}/validate`);

if (res.status === 500) {
throw new Error((res.data as unknown as { message: string }).message);
throw new Error((res.data as unknown as {message: string}).message);
}

return res.data;
Expand Down Expand Up @@ -208,7 +208,7 @@ export interface EndpointType {
export function splitMultichainDataFields(fieldStr: string): MultichainDataFieldType {
const result: MultichainDataFieldType = {};

splitEndpoints(String(fieldStr)).forEach(unparsedRow => {
splitEndpoints(String(fieldStr)).forEach((unparsedRow) => {
let regexpResult: string[] = unparsedRow.match(/(.*?):(.*)/);
if (regexpResult) {
regexpResult = Object.values(regexpResult);
Expand All @@ -221,52 +221,51 @@ export function splitMultichainDataFields(fieldStr: string): MultichainDataField
return result;
}

export const DefaultDeployFlags: FlagInput<DeploymentFlagsInterface> =
{
org: Flags.string({description: 'Enter organization name'}),
projectName: Flags.string({description: 'Enter project name'}),
// ipfsCID: Flags.string({description: 'Enter IPFS CID'}),

type: Flags.string({options: ['stage', 'primary'], default: DEFAULT_DEPLOYMENT_TYPE, required: false}),
indexerVersion: Flags.string({description: 'Enter indexer-version', required: false}),
queryVersion: Flags.string({description: 'Enter query-version', required: false}),
dict: Flags.string({description: 'Enter dictionary', required: false}),
endpoint: Flags.string({description: 'Enter endpoint', required: false}),
//indexer set up flags
indexerUnsafe: Flags.boolean({description: 'Enable indexer unsafe', required: false}),
indexerBatchSize: Flags.integer({description: 'Enter batchSize from 1 to 30', required: false}),
indexerSubscription: Flags.boolean({description: 'Enable Indexer subscription', required: false}),
disableHistorical: Flags.boolean({description: 'Disable Historical Data', required: false}),
indexerUnfinalized: Flags.boolean({
description: 'Index unfinalized blocks (requires Historical to be enabled)',
required: false,
}),
indexerStoreCacheThreshold: Flags.integer({
description: 'The number of items kept in the cache before flushing',
required: false,
}),
disableIndexerStoreCacheAsync: Flags.boolean({
description: 'If enabled the store cache will flush data asynchronously relative to indexing data.',
required: false,
}),
indexerWorkers: Flags.integer({description: 'Enter worker threads from 1 to 5', required: false, max: 5}),

//query flags
queryUnsafe: Flags.boolean({description: 'Enable indexer unsafe', required: false}),
querySubscription: Flags.boolean({description: 'Enable Query subscription', required: false}),
queryTimeout: Flags.integer({description: 'Enter timeout from 1000ms to 60000ms', required: false}),
queryMaxConnection: Flags.integer({description: 'Enter MaxConnection from 1 to 10', required: false}),
queryAggregate: Flags.boolean({description: 'Enable Aggregate', required: false}),

useDefaults: Flags.boolean({
char: 'd',
description: 'Use default values for indexerVersion, queryVersion, dictionary, endpoint',
required: false,
})
};


export function generateDeploymentChain(row: GenerateDeploymentChainInterface) {
export const DefaultDeployFlags = {
org: Flags.string({description: 'Enter organization name'}),
projectName: Flags.string({description: 'Enter project name'}),
// ipfsCID: Flags.string({description: 'Enter IPFS CID'}),

type: Flags.string({options: ['stage', 'primary'], default: DEFAULT_DEPLOYMENT_TYPE, required: false}),
indexerVersion: Flags.string({description: 'Enter indexer-version', required: false}),
queryVersion: Flags.string({description: 'Enter query-version', required: false}),
dict: Flags.string({description: 'Enter dictionary', required: false}),
endpoint: Flags.string({description: 'Enter endpoint', required: false}),
//indexer set up flags
indexerUnsafe: Flags.boolean({description: 'Enable indexer unsafe', required: false}),
indexerBatchSize: Flags.integer({description: 'Enter batchSize from 1 to 30', required: false}),
indexerSubscription: Flags.boolean({description: 'Enable Indexer subscription', required: false}),
disableHistorical: Flags.boolean({description: 'Disable Historical Data', required: false}),
indexerUnfinalized: Flags.boolean({
description: 'Index unfinalized blocks (requires Historical to be enabled)',
required: false,
}),
indexerStoreCacheThreshold: Flags.integer({
description: 'The number of items kept in the cache before flushing',
required: false,
}),
disableIndexerStoreCacheAsync: Flags.boolean({
description: 'If enabled the store cache will flush data asynchronously relative to indexing data.',
required: false,
}),
indexerWorkers: Flags.integer({description: 'Enter worker threads from 1 to 5', required: false, max: 5}),

//query flags
queryUnsafe: Flags.boolean({description: 'Enable indexer unsafe', required: false}),
querySubscription: Flags.boolean({description: 'Enable Query subscription', required: false}),
queryTimeout: Flags.integer({description: 'Enter timeout from 1000ms to 60000ms', required: false}),
queryMaxConnection: Flags.integer({description: 'Enter MaxConnection from 1 to 10', required: false}),
queryAggregate: Flags.boolean({description: 'Enable Aggregate', required: false}),
queryLimit: Flags.integer({description: 'Set the max number of results the query service returns', required: false}),

useDefaults: Flags.boolean({
char: 'd',
description: 'Use default values for indexerVersion, queryVersion, dictionary, endpoint',
required: false,
}),
} satisfies FlagInput<DeploymentFlagsInterface>;

export function generateDeploymentChain(row: GenerateDeploymentChainInterface): V3DeploymentIndexerType {
return {
cid: row.cid,
dictEndpoint: row.dictEndpoint,
Expand All @@ -283,13 +282,13 @@ export function generateDeploymentChain(row: GenerateDeploymentChainInterface) {
disableStoreCacheAsync: row.flags.disableIndexerStoreCacheAsync,
},
},
extraParams: row.flags.indexerWorkers ?
{
workers: {
num: row.flags.indexerWorkers,
},
} :
{}
extraParams: row.flags.indexerWorkers
? {
workers: {
num: row.flags.indexerWorkers,
},
}
: {},
};
}

Expand All @@ -298,12 +297,12 @@ export function generateAdvancedQueryOptions(flags: DeploymentFlagsInterface): Q
unsafe: !!flags.queryUnsafe,
subscription: !!flags.querySubscription,
queryTimeout: Number(flags.queryTimeout),
queryLimit: flags.queryLimit ? Number(flags.queryLimit) : undefined,
// maxConnection: Number(flags.queryMaxConnection), // project version or plan does not support maxConnection
aggregate: !!flags.queryAggregate,
}
};
}


export async function executeProjectDeployment(data: ProjectDeploymentInterface): Promise<DeploymentDataType | void> {
let deploymentOutput: DeploymentDataType | void;

Expand Down Expand Up @@ -332,7 +331,7 @@ export async function executeProjectDeployment(data: ProjectDeploymentInterface)
data.chains,
ROOT_API_URL_PROD
).catch((e) => {
throw e
throw e;
});

if (deploymentOutput) {
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface QueryAdvancedOpts {
subscription?: boolean;
queryTimeout?: number;
maxConnection?: number;
queryLimit?: number;
aggregate?: boolean;
}
export interface IndexerAdvancedOpts {
Expand Down Expand Up @@ -186,6 +187,7 @@ export interface DeploymentFlagsInterface {
queryTimeout: number;
queryMaxConnection: number;
queryAggregate: boolean;
queryLimit?: number;
useDefaults: boolean;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export async function checkToken(token_path: string = ACCESS_TOKEN_PATH): Promis
if (!authToken) {
return await cli.prompt('Token cannot be found, Enter token');
}
return authToken;
return authToken.trim();
} catch (e) {
return cli.prompt('Token cannot be found, Enter token');
}
Expand Down
Loading
Loading