Skip to content

Commit

Permalink
🔀 Merge pull request #1637 from sadlowskij/v4/feature/alexa-cli-verif…
Browse files Browse the repository at this point in the history
…y-certify

✨ Add verify and certify commands to alexa cli plugin
  • Loading branch information
jankoenig authored Jun 6, 2024
2 parents 7e3e4b3 + a24262c commit 347ab53
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 3 deletions.
40 changes: 39 additions & 1 deletion platforms/platform-alexa/docs/cli-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ The Alexa CLI plugin hooks into the following commands:
- [`deploy`](#deploy): Deploy project files to the Alexa Developer Console
- [`get`](#get): Synchronize your local project files with the Alexa Developer Console

Also it provides the following platform specific commands:

- [`validate:alexa`](#validate): Trigger the Alexa Skill Validation
- [`certify:alexa`](#certify): Trigger the Alexa Skill Certification

## build

The Alexa CLI plugin hooks into the `build` command and creates a `platform.alexa` folder inside the `build` directory in the root of your Jovo project. [Learn more about the `build` command here](https://www.jovo.tech/docs/build-command).
Expand Down Expand Up @@ -132,4 +137,37 @@ $ jovo get:platform alexa

# Turn Alexa Interaction Model into Jovo Model
$ jovo build:platform alexa --reverse
```
```

## validate

The Alexa CLI plugin provides a command to easily trigger a Skill Validation.

```sh
$ jovo verify:alexa
```

After successfully triggering the validation, you can check the status in the [Alexa Developer Console](https://developer.amazon.com/alexa/console/ask#/).

| Flag | Description | Examples |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| `--skill-stage` | Either `development`, `live` or `certification` depending on what skill stage is to be validated. Default is `development` | `jovo validate:alexa --skill-stage development` | | |
| `--skill-id` | The skillId of the to be validated skill. If not provided, will be taken from the stage in the project configuration. [Learn more about ASK skillId configuration here](./project-config.md#skillid) | `jovo validate:alexa --skill-id amzn1.ask.skill.123example` |
| `--ask-profile` | Deploy to using the specified ASK profile. If not provided as flag, will be taken from project configuration. [Learn more about ASK profile configuration here](./project-config.md#askprofile) | `jovo validate:alexa --ask-profile default` |
| `--locales` | List of locales in which to validate the skill. If not provided, will do for all locales in project configuration. [Learn more about locales configuration here](./project-config.md#locales) | `jovo validate:alexa --locales en-US de-DE` |

## certify

The Alexa CLI plugin provides a command to easily trigger a Skill Certification.

```sh
$ jovo certify:alexa
```

After successfully triggering the certification, you can check the status of the certification in the [Alexa Developer Console](https://developer.amazon.com/alexa/console/ask#/).

| Flag | Description | Examples |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| `--skill-id` | The skillId of the to be validated skill. If not provided, will be taken from the stage in the project configuration. [Learn more about ASK skillId configuration here](./project-config.md#skillid) | `jovo certify:alexa --skill-id amzn1.ask.skill.123example` |
| `--ask-profile` | Deploy to using the specified ASK profile. If not provided as flag, will be taken from project configuration. [Learn more about ASK profile configuration here](./project-config.md#askprofile) | `jovo certify:alexa --ask-profile default` |
| `--publication-method` | Either `MANUAL_PUBLISHING` or `AUTO_PUBLISHING`. Default is `MANUAL_PUBLISHING`. [Learn more about publication methods](https://developer.amazon.com/en-US/docs/alexa/smapi/ask-cli-command-reference.html#submit-skill-for-certification-subcommand) | `jovo validate:alexa --publication-method AUTO_PUBLISHING` |
44 changes: 44 additions & 0 deletions platforms/platform-alexa/src/cli/commands/CertifyCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { JovoCliError, MAGNIFYING_GLASS, PluginCommand, Task, flags } from '@jovotech/cli-core';
import * as smapi from '../smapi';
import { AlexaCli } from '..';
import { PublicationMethodLike, PublicationMethod } from '../interfaces';

export class CertifyCommand extends PluginCommand {
$plugin!: AlexaCli;
static id = 'certify:alexa';
static description = 'This submits an alexa skill to certification';
static examples: string[] = ['jovo certify:alexa'];
static flags = {
...PluginCommand.flags,
'skill-id': flags.string({ char: 's', description: 'Alexa Skill ID' }),
'ask-profile': flags.string({
description: 'Name of used ASK profile',
}),
'publication-method': flags.string({
options: Object.values(PublicationMethod),
default: PublicationMethod.MANUAL_PUBLISHING,
}),
};
static args = [];

async run(): Promise<void> {
const { flags } = this.parse(CertifyCommand);
const skillId = flags['skill-id'] || this.$plugin.config.skillId;
const askProfile = flags['ask-profile'] || this.$plugin.config.askProfile || 'default';
const publicationMethod: PublicationMethodLike = flags['publication-method'];

const certifyTask: Task = new Task(
`${MAGNIFYING_GLASS} Submitting Alexa Skill ${skillId} to Certification`,
async () => {
if (!skillId)
throw new JovoCliError({
message: 'Cannot submit Skill to Certification without skillId',
hint: 'Either add a skillId to the stage in the project configuration or add the --skill-id flag',
});

return smapi.submitSkillForCertification(skillId, publicationMethod, askProfile);
},
);
await certifyTask.run();
}
}
63 changes: 63 additions & 0 deletions platforms/platform-alexa/src/cli/commands/ValidateCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {
JovoCliError,
Log,
MAGNIFYING_GLASS,
PluginCommand,
Task,
flags,
} from '@jovotech/cli-core';
import * as smapi from '../smapi';
import { AlexaCli } from '..';

export class ValidateCommand extends PluginCommand {
$plugin!: AlexaCli;
static id = 'validate:alexa';
static description = 'This submits a skill validation';
static examples: string[] = ['jovo validate:alexa'];
static flags = {
'skill-stage': flags.string({
description: 'Alexa Skill Stage',
options: ['development', 'live', 'certification'],
default: 'development',
}),
'skill-id': flags.string({ char: 's', description: 'Alexa Skill ID' }),
'ask-profile': flags.string({
description: 'Name of used ASK profile',
}),
'locales': flags.string({ multiple: true, char: 'l' }),
...PluginCommand.flags,
};
static args = [];

async run(): Promise<void> {
const { flags } = this.parse(ValidateCommand);
const skillId = flags['skill-id'] || this.$plugin.config.skillId;
const askProfile = flags['ask-profile'] || this.$plugin.config.askProfile || 'default';
const locales =
flags.locales ||
Object.values(this.$plugin.config.locales || {}).reduce(
(prev, curr) => [...prev, ...curr],
[],
);

const validateTask: Task = new Task(
`${MAGNIFYING_GLASS} Submitting Alexa Skill ${skillId} to Validation`,
async () => {
if (!skillId)
throw new JovoCliError({
message: 'Cannot submit Skill Validation without skillId',
hint: 'Either add a skillId to the stage in the project configuration or add the --skill-id flag',
});

const validationResponse = await smapi.submitSkillValidation(
skillId,
locales,
flags['skill-stage'],
askProfile,
);
return `Started Validation with id ${validationResponse.id}`;
},
);
await validateTask.run();
}
}
7 changes: 7 additions & 0 deletions platforms/platform-alexa/src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { NewContext } from '@jovotech/cli-command-new';
import {
JovoCliPlugin,
Log,
PluginCommand,
PluginHook,
PluginType,
promptSupportedLocales,
Expand All @@ -15,6 +16,8 @@ import { DeployHook } from './hooks/DeployHook';
import { GetHook } from './hooks/GetHook';
import { NewHook } from './hooks/NewHook';
import { AlexaCliConfig, AlexaConversationsConfig, SupportedLocalesType } from './interfaces';
import { CertifyCommand } from './commands/CertifyCommand';
import { ValidateCommand } from './commands/ValidateCommand';

export type AlexaCliInitConfig =
| RequiredOnlyWhere<AlexaCliConfig, 'conversations.enabled'>
Expand Down Expand Up @@ -105,6 +108,10 @@ export class AlexaCli extends JovoCliPlugin<AlexaCliConfig> {
return [BuildHook, GetHook, DeployHook, NewHook];
}

getCommands(): (typeof PluginCommand)[] {
return [CertifyCommand, ValidateCommand];
}

/**
* The base path to platform's build folder
*/
Expand Down
16 changes: 15 additions & 1 deletion platforms/platform-alexa/src/cli/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { PluginConfig, PluginContext } from '@jovotech/cli-core';
import { UnknownObject } from '@jovotech/framework';
import { EnumLike, UnknownObject } from '@jovotech/framework';
import { ConversationsTarget } from '../interfaces';

import { SupportedLocales } from './constants';
Expand Down Expand Up @@ -116,3 +116,17 @@ export interface SkillStatusResponse {
};
interactionModel?: UnknownObject;
}

export enum PublicationMethod {
MANUAL_PUBLISHING = 'MANUAL_PUBLISHING',
AUTO_PUBLISHING = 'AUTO_PUBLISHING',
}

export type PublicationMethodLike = EnumLike<PublicationMethod> | string;

export type ValidationStatus = 'SUCCEEDED' | 'FAILED' | 'IN_PROGRESS';

export interface SkillValidationResponse {
id: string;
status: ValidationStatus;
}
46 changes: 45 additions & 1 deletion platforms/platform-alexa/src/cli/smapi/SkillManagement.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { JovoCliError, wait } from '@jovotech/cli-core';
import { AskSkillList, SkillStatusError, SkillStatusResponse } from '../interfaces';
import {
AskSkillList,
SkillStatusError,
SkillStatusResponse,
SkillValidationResponse,
} from '../interfaces';
import { execAskCommand } from '../utilities';
import { PublicationMethodLike } from '../interfaces';

export async function listSkills(askProfile?: string): Promise<AskSkillList> {
const { stdout } = await execAskCommand(
Expand Down Expand Up @@ -45,3 +51,41 @@ export async function getSkillStatus(skillId: string, askProfile?: string): Prom
}
}
}

export async function submitSkillForCertification(
skillId: string,
publicationMethod: PublicationMethodLike,
askProfile?: string,
): Promise<string | undefined> {
const { stdout } = await execAskCommand(
'smapiSubmitSkillForCertification',
[
'ask smapi submit-skill-for-certification',
`-s ${skillId}`,
`--publication-method ${publicationMethod}`,
],
askProfile,
);

return stdout;
}

export async function submitSkillValidation(
skillId: string,
locales: string[],
stage: string,
askProfile?: string,
): Promise<SkillValidationResponse> {
const { stdout } = await execAskCommand(
'smapiSubmitSkillValidation',
[
'ask smapi submit-skill-validation',
`-s ${skillId}`,
`--stage ${stage}`,
`--locales ${locales.join(' ')}`,
],
askProfile,
);

return JSON.parse(stdout!);
}

0 comments on commit 347ab53

Please sign in to comment.