Merge pull request #9559 from backstage/rugvip/intype
scaffolder-backend: update TemplateAction to use more precise types
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': minor
|
||||
---
|
||||
|
||||
**BREAKING**: Updated `TemplateAction` and related types to have its type parameter extend `JsonObject` instead of `InputBase`. The `createTemplateAction` has also been updated to pass through the `TInput` type parameter to the return type, meaning the `TemplateAction` retains its type. This can lead to breakages during type checking especially within tests.
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-cookiecutter': minor
|
||||
'@backstage/plugin-scaffolder-backend-module-rails': minor
|
||||
'@backstage/plugin-scaffolder-backend-module-yeoman': minor
|
||||
---
|
||||
|
||||
Updated to the latest version of `@backstage/plugin-scaffolder-backend`, meaning the `TemplateAction` now exposes the precise input type rather than `any`.
|
||||
@@ -6,6 +6,7 @@
|
||||
/// <reference types="node" />
|
||||
|
||||
import { ContainerRunner } from '@backstage/backend-common';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import { TemplateAction } from '@backstage/plugin-scaffolder-backend';
|
||||
import { UrlReader } from '@backstage/backend-common';
|
||||
@@ -15,5 +16,12 @@ export function createFetchCookiecutterAction(options: {
|
||||
reader: UrlReader;
|
||||
integrations: ScmIntegrations;
|
||||
containerRunner: ContainerRunner;
|
||||
}): TemplateAction<any>;
|
||||
}): TemplateAction<{
|
||||
url: string;
|
||||
targetPath?: string | undefined;
|
||||
values: JsonObject;
|
||||
copyWithoutRender?: string[] | undefined;
|
||||
extensions?: string[] | undefined;
|
||||
imageName?: string | undefined;
|
||||
}>;
|
||||
```
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
```ts
|
||||
import { ContainerRunner } from '@backstage/backend-common';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import { TemplateAction } from '@backstage/plugin-scaffolder-backend';
|
||||
import { UrlReader } from '@backstage/backend-common';
|
||||
@@ -13,5 +14,10 @@ export function createFetchRailsAction(options: {
|
||||
reader: UrlReader;
|
||||
integrations: ScmIntegrations;
|
||||
containerRunner: ContainerRunner;
|
||||
}): TemplateAction<any>;
|
||||
}): TemplateAction<{
|
||||
url: string;
|
||||
targetPath?: string | undefined;
|
||||
values: JsonObject;
|
||||
imageName?: string | undefined;
|
||||
}>;
|
||||
```
|
||||
|
||||
@@ -3,8 +3,13 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { TemplateAction } from '@backstage/plugin-scaffolder-backend';
|
||||
|
||||
// @public
|
||||
export function createRunYeomanAction(): TemplateAction<any>;
|
||||
export function createRunYeomanAction(): TemplateAction<{
|
||||
namespace: string;
|
||||
args?: string[] | undefined;
|
||||
options?: JsonObject | undefined;
|
||||
}>;
|
||||
```
|
||||
|
||||
@@ -34,11 +34,10 @@ import { TemplateMetadata } from '@backstage/plugin-scaffolder-common';
|
||||
import { UrlReader } from '@backstage/backend-common';
|
||||
import { Writable } from 'stream';
|
||||
|
||||
// Warning: (ae-forgotten-export) The symbol "InputBase" needs to be exported by the entry point index.d.ts
|
||||
// Warning: (ae-missing-release-tag) "ActionContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export type ActionContext<Input extends InputBase> = {
|
||||
export type ActionContext<Input extends JsonObject> = {
|
||||
baseUrl?: string;
|
||||
logger: Logger_2;
|
||||
logStream: Writable;
|
||||
@@ -77,7 +76,7 @@ export const createBuiltinActions: (options: {
|
||||
containerRunner?: ContainerRunner;
|
||||
config: Config;
|
||||
additionalTemplateFilters?: Record<string, TemplateFilter>;
|
||||
}) => TemplateAction<any>[];
|
||||
}) => TemplateAction<JsonObject>[];
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createCatalogRegisterAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
@@ -85,17 +84,33 @@ export const createBuiltinActions: (options: {
|
||||
export function createCatalogRegisterAction(options: {
|
||||
catalogClient: CatalogApi;
|
||||
integrations: ScmIntegrations;
|
||||
}): TemplateAction<any>;
|
||||
}): TemplateAction<
|
||||
| {
|
||||
catalogInfoUrl: string;
|
||||
optional?: boolean | undefined;
|
||||
}
|
||||
| {
|
||||
repoContentsUrl: string;
|
||||
catalogInfoPath?: string | undefined;
|
||||
optional?: boolean | undefined;
|
||||
}
|
||||
>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createCatalogWriteAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export function createCatalogWriteAction(): TemplateAction<any>;
|
||||
export function createCatalogWriteAction(): TemplateAction<{
|
||||
filePath?: string | undefined;
|
||||
entity: Entity;
|
||||
}>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createDebugLogAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public
|
||||
export function createDebugLogAction(): TemplateAction<any>;
|
||||
export function createDebugLogAction(): TemplateAction<{
|
||||
message?: string | undefined;
|
||||
listWorkspace?: boolean | undefined;
|
||||
}>;
|
||||
|
||||
export { createFetchCookiecutterAction };
|
||||
|
||||
@@ -105,7 +120,10 @@ export { createFetchCookiecutterAction };
|
||||
export function createFetchPlainAction(options: {
|
||||
reader: UrlReader;
|
||||
integrations: ScmIntegrations;
|
||||
}): TemplateAction<any>;
|
||||
}): TemplateAction<{
|
||||
url: string;
|
||||
targetPath?: string | undefined;
|
||||
}>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createFetchTemplateAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
@@ -114,17 +132,32 @@ export function createFetchTemplateAction(options: {
|
||||
reader: UrlReader;
|
||||
integrations: ScmIntegrations;
|
||||
additionalTemplateFilters?: Record<string, TemplateFilter>;
|
||||
}): TemplateAction<any>;
|
||||
}): TemplateAction<{
|
||||
url: string;
|
||||
targetPath?: string | undefined;
|
||||
values: any;
|
||||
templateFileExtension?: string | boolean | undefined;
|
||||
copyWithoutRender?: string[] | undefined;
|
||||
cookiecutterCompat?: boolean | undefined;
|
||||
}>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createFilesystemDeleteAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export const createFilesystemDeleteAction: () => TemplateAction<any>;
|
||||
export const createFilesystemDeleteAction: () => TemplateAction<{
|
||||
files: string[];
|
||||
}>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createFilesystemRenameAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export const createFilesystemRenameAction: () => TemplateAction<any>;
|
||||
export const createFilesystemRenameAction: () => TemplateAction<{
|
||||
files: Array<{
|
||||
from: string;
|
||||
to: string;
|
||||
overwrite?: boolean;
|
||||
}>;
|
||||
}>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createGithubActionsDispatchAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
@@ -132,7 +165,17 @@ export const createFilesystemRenameAction: () => TemplateAction<any>;
|
||||
export function createGithubActionsDispatchAction(options: {
|
||||
integrations: ScmIntegrations;
|
||||
githubCredentialsProvider?: GithubCredentialsProvider;
|
||||
}): TemplateAction<any>;
|
||||
}): TemplateAction<{
|
||||
repoUrl: string;
|
||||
workflowId: string;
|
||||
branchOrTagName: string;
|
||||
workflowInputs?:
|
||||
| {
|
||||
[key: string]: string;
|
||||
}
|
||||
| undefined;
|
||||
token?: string | undefined;
|
||||
}>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createGithubWebhookAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
@@ -141,7 +184,16 @@ export function createGithubWebhookAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
defaultWebhookSecret?: string;
|
||||
githubCredentialsProvider?: GithubCredentialsProvider;
|
||||
}): TemplateAction<any>;
|
||||
}): TemplateAction<{
|
||||
repoUrl: string;
|
||||
webhookUrl: string;
|
||||
webhookSecret?: string | undefined;
|
||||
events?: string[] | undefined;
|
||||
active?: boolean | undefined;
|
||||
contentType?: 'form' | 'json' | undefined;
|
||||
insecureSsl?: boolean | undefined;
|
||||
token?: string | undefined;
|
||||
}>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createPublishAzureAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
@@ -149,7 +201,13 @@ export function createGithubWebhookAction(options: {
|
||||
export function createPublishAzureAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
config: Config;
|
||||
}): TemplateAction<any>;
|
||||
}): TemplateAction<{
|
||||
repoUrl: string;
|
||||
description?: string | undefined;
|
||||
defaultBranch?: string | undefined;
|
||||
sourcePath?: string | undefined;
|
||||
token?: string | undefined;
|
||||
}>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createPublishBitbucketAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
@@ -157,12 +215,22 @@ export function createPublishAzureAction(options: {
|
||||
export function createPublishBitbucketAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
config: Config;
|
||||
}): TemplateAction<any>;
|
||||
}): TemplateAction<{
|
||||
repoUrl: string;
|
||||
description?: string | undefined;
|
||||
defaultBranch?: string | undefined;
|
||||
repoVisibility?: 'private' | 'public' | undefined;
|
||||
sourcePath?: string | undefined;
|
||||
enableLFS?: boolean | undefined;
|
||||
token?: string | undefined;
|
||||
}>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createPublishFileAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public
|
||||
export function createPublishFileAction(): TemplateAction<any>;
|
||||
export function createPublishFileAction(): TemplateAction<{
|
||||
path: string;
|
||||
}>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createPublishGithubAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
@@ -171,7 +239,23 @@ export function createPublishGithubAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
config: Config;
|
||||
githubCredentialsProvider?: GithubCredentialsProvider;
|
||||
}): TemplateAction<any>;
|
||||
}): TemplateAction<{
|
||||
repoUrl: string;
|
||||
description?: string | undefined;
|
||||
access?: string | undefined;
|
||||
defaultBranch?: string | undefined;
|
||||
sourcePath?: string | undefined;
|
||||
requireCodeOwnerReviews?: boolean | undefined;
|
||||
repoVisibility?: 'internal' | 'private' | 'public' | undefined;
|
||||
collaborators?:
|
||||
| {
|
||||
username: string;
|
||||
access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
|
||||
}[]
|
||||
| undefined;
|
||||
token?: string | undefined;
|
||||
topics?: string[] | undefined;
|
||||
}>;
|
||||
|
||||
// Warning: (ae-forgotten-export) The symbol "CreateGithubPullRequestActionOptions" needs to be exported by the entry point index.d.ts
|
||||
// Warning: (ae-missing-release-tag) "createPublishGithubPullRequestAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
@@ -181,7 +265,15 @@ export const createPublishGithubPullRequestAction: ({
|
||||
integrations,
|
||||
githubCredentialsProvider,
|
||||
clientFactory,
|
||||
}: CreateGithubPullRequestActionOptions) => TemplateAction<any>;
|
||||
}: CreateGithubPullRequestActionOptions) => TemplateAction<{
|
||||
title: string;
|
||||
branchName: string;
|
||||
description: string;
|
||||
repoUrl: string;
|
||||
targetPath?: string | undefined;
|
||||
sourcePath?: string | undefined;
|
||||
token?: string | undefined;
|
||||
}>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createPublishGitlabAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
@@ -189,14 +281,28 @@ export const createPublishGithubPullRequestAction: ({
|
||||
export function createPublishGitlabAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
config: Config;
|
||||
}): TemplateAction<any>;
|
||||
}): TemplateAction<{
|
||||
repoUrl: string;
|
||||
defaultBranch?: string | undefined;
|
||||
repoVisibility?: 'internal' | 'private' | 'public' | undefined;
|
||||
sourcePath?: string | undefined;
|
||||
token?: string | undefined;
|
||||
}>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createPublishGitlabMergeRequestAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export const createPublishGitlabMergeRequestAction: (options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
}) => TemplateAction<any>;
|
||||
}) => TemplateAction<{
|
||||
projectid: string;
|
||||
repoUrl: string;
|
||||
title: string;
|
||||
description: string;
|
||||
branchName: string;
|
||||
targetPath: string;
|
||||
token?: string | undefined;
|
||||
}>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createRouter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
@@ -206,13 +312,9 @@ export function createRouter(options: RouterOptions): Promise<express.Router>;
|
||||
// Warning: (ae-missing-release-tag) "createTemplateAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export const createTemplateAction: <
|
||||
Input extends Partial<{
|
||||
[name: string]: JsonValue | Partial<JsonObject> | undefined;
|
||||
}>,
|
||||
>(
|
||||
templateAction: TemplateAction<Input>,
|
||||
) => TemplateAction<any>;
|
||||
export const createTemplateAction: <TInput extends JsonObject>(
|
||||
templateAction: TemplateAction<TInput>,
|
||||
) => TemplateAction<TInput>;
|
||||
|
||||
// @public
|
||||
export type CreateWorkerOptions = {
|
||||
@@ -531,7 +633,7 @@ export class TaskWorker {
|
||||
// Warning: (ae-missing-release-tag) "TemplateAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export type TemplateAction<Input extends InputBase> = {
|
||||
export type TemplateAction<Input extends JsonObject> = {
|
||||
id: string;
|
||||
description?: string;
|
||||
schema?: {
|
||||
@@ -546,13 +648,11 @@ export type TemplateAction<Input extends InputBase> = {
|
||||
// @public (undocumented)
|
||||
export class TemplateActionRegistry {
|
||||
// (undocumented)
|
||||
get(actionId: string): TemplateAction<any>;
|
||||
get(actionId: string): TemplateAction<JsonObject>;
|
||||
// (undocumented)
|
||||
list(): TemplateAction<any>[];
|
||||
list(): TemplateAction<JsonObject>[];
|
||||
// (undocumented)
|
||||
register<Parameters extends InputBase>(
|
||||
action: TemplateAction<Parameters>,
|
||||
): void;
|
||||
register<TInput extends JsonObject>(action: TemplateAction<TInput>): void;
|
||||
}
|
||||
|
||||
// Warning: (ae-missing-release-tag) "TemplateFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
|
||||
@@ -14,13 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { InputBase, TemplateAction } from './types';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { ConflictError, NotFoundError } from '@backstage/errors';
|
||||
import { TemplateAction } from './types';
|
||||
|
||||
export class TemplateActionRegistry {
|
||||
private readonly actions = new Map<string, TemplateAction<any>>();
|
||||
|
||||
register<Parameters extends InputBase>(action: TemplateAction<Parameters>) {
|
||||
register<TInput extends JsonObject>(action: TemplateAction<TInput>) {
|
||||
if (this.actions.has(action.id)) {
|
||||
throw new ConflictError(
|
||||
`Template action with ID '${action.id}' has already been registered`,
|
||||
@@ -29,7 +30,7 @@ export class TemplateActionRegistry {
|
||||
this.actions.set(action.id, action);
|
||||
}
|
||||
|
||||
get(actionId: string): TemplateAction<any> {
|
||||
get(actionId: string): TemplateAction<JsonObject> {
|
||||
const action = this.actions.get(actionId);
|
||||
if (!action) {
|
||||
throw new NotFoundError(
|
||||
@@ -39,7 +40,7 @@ export class TemplateActionRegistry {
|
||||
return action;
|
||||
}
|
||||
|
||||
list(): TemplateAction<any>[] {
|
||||
list(): TemplateAction<JsonObject>[] {
|
||||
return [...this.actions.values()];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import { ContainerRunner, UrlReader } from '@backstage/backend-common';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import {
|
||||
GithubCredentialsProvider,
|
||||
@@ -47,6 +48,7 @@ import {
|
||||
createGithubWebhookAction,
|
||||
} from './github';
|
||||
import { TemplateFilter } from '../../../lib';
|
||||
import { TemplateAction } from '../types';
|
||||
|
||||
export const createBuiltinActions = (options: {
|
||||
reader: UrlReader;
|
||||
@@ -55,7 +57,7 @@ export const createBuiltinActions = (options: {
|
||||
containerRunner?: ContainerRunner;
|
||||
config: Config;
|
||||
additionalTemplateFilters?: Record<string, TemplateFilter>;
|
||||
}) => {
|
||||
}): TemplateAction<JsonObject>[] => {
|
||||
const {
|
||||
reader,
|
||||
integrations,
|
||||
@@ -126,5 +128,5 @@ export const createBuiltinActions = (options: {
|
||||
);
|
||||
}
|
||||
|
||||
return actions;
|
||||
return actions as TemplateAction<JsonObject>[];
|
||||
};
|
||||
|
||||
@@ -61,7 +61,7 @@ describe('debug:log', () => {
|
||||
const context = {
|
||||
...mockContext,
|
||||
input: {
|
||||
listWorkspace: 'true',
|
||||
listWorkspace: true,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -27,12 +27,18 @@ import { ScmIntegrations } from '@backstage/integration';
|
||||
import { PassThrough } from 'stream';
|
||||
import { fetchContents } from './helpers';
|
||||
import { ActionContext, TemplateAction } from '../../types';
|
||||
import { createFetchTemplateAction, FetchTemplateInput } from './template';
|
||||
import { createFetchTemplateAction } from './template';
|
||||
|
||||
jest.mock('./helpers', () => ({
|
||||
fetchContents: jest.fn(),
|
||||
}));
|
||||
|
||||
type FetchTemplateInput = ReturnType<
|
||||
typeof createFetchTemplateAction
|
||||
> extends TemplateAction<infer U>
|
||||
? U
|
||||
: never;
|
||||
|
||||
const realFiles = Object.fromEntries(
|
||||
[
|
||||
resolvePackagePath(
|
||||
|
||||
@@ -28,22 +28,6 @@ import {
|
||||
SecureTemplater,
|
||||
} from '../../../../lib/templating/SecureTemplater';
|
||||
|
||||
type CookieCompatInput = {
|
||||
copyWithoutRender?: string[];
|
||||
cookiecutterCompat?: boolean;
|
||||
};
|
||||
|
||||
type ExtensionInput = {
|
||||
templateFileExtension?: string | boolean;
|
||||
};
|
||||
|
||||
export type FetchTemplateInput = {
|
||||
url: string;
|
||||
targetPath?: string;
|
||||
values: any;
|
||||
} & CookieCompatInput &
|
||||
ExtensionInput;
|
||||
|
||||
export function createFetchTemplateAction(options: {
|
||||
reader: UrlReader;
|
||||
integrations: ScmIntegrations;
|
||||
@@ -51,7 +35,16 @@ export function createFetchTemplateAction(options: {
|
||||
}) {
|
||||
const { reader, integrations, additionalTemplateFilters } = options;
|
||||
|
||||
return createTemplateAction<FetchTemplateInput>({
|
||||
return createTemplateAction<{
|
||||
url: string;
|
||||
targetPath?: string;
|
||||
values: any;
|
||||
templateFileExtension?: string | boolean;
|
||||
|
||||
// Cookiecutter compat options
|
||||
copyWithoutRender?: string[];
|
||||
cookiecutterCompat?: boolean;
|
||||
}>({
|
||||
id: 'fetch:template',
|
||||
description:
|
||||
"Downloads a skeleton, templates variables into file and directory names and content, and places the result in the workspace, or optionally in a subdirectory specified by the 'targetPath' input option.",
|
||||
|
||||
@@ -61,28 +61,28 @@ describe('fs:delete', () => {
|
||||
await expect(
|
||||
action.handler({
|
||||
...mockContext,
|
||||
input: { files: undefined },
|
||||
input: { files: undefined } as any,
|
||||
}),
|
||||
).rejects.toThrow(/files must be an Array/);
|
||||
|
||||
await expect(
|
||||
action.handler({
|
||||
...mockContext,
|
||||
input: { files: {} },
|
||||
input: { files: {} } as any,
|
||||
}),
|
||||
).rejects.toThrow(/files must be an Array/);
|
||||
|
||||
await expect(
|
||||
action.handler({
|
||||
...mockContext,
|
||||
input: { files: '' },
|
||||
input: { files: '' } as any,
|
||||
}),
|
||||
).rejects.toThrow(/files must be an Array/);
|
||||
|
||||
await expect(
|
||||
action.handler({
|
||||
...mockContext,
|
||||
input: { files: null },
|
||||
input: { files: null } as any,
|
||||
}),
|
||||
).rejects.toThrow(/files must be an Array/);
|
||||
});
|
||||
|
||||
@@ -76,28 +76,28 @@ describe('fs:rename', () => {
|
||||
await expect(
|
||||
action.handler({
|
||||
...mockContext,
|
||||
input: { files: undefined },
|
||||
input: { files: undefined } as any,
|
||||
}),
|
||||
).rejects.toThrow(/files must be an Array/);
|
||||
|
||||
await expect(
|
||||
action.handler({
|
||||
...mockContext,
|
||||
input: { files: {} },
|
||||
input: { files: {} } as any,
|
||||
}),
|
||||
).rejects.toThrow(/files must be an Array/);
|
||||
|
||||
await expect(
|
||||
action.handler({
|
||||
...mockContext,
|
||||
input: { files: '' },
|
||||
input: { files: '' } as any,
|
||||
}),
|
||||
).rejects.toThrow(/files must be an Array/);
|
||||
|
||||
await expect(
|
||||
action.handler({
|
||||
...mockContext,
|
||||
input: { files: null },
|
||||
input: { files: null } as any,
|
||||
}),
|
||||
).rejects.toThrow(/files must be an Array/);
|
||||
});
|
||||
@@ -106,21 +106,21 @@ describe('fs:rename', () => {
|
||||
await expect(
|
||||
action.handler({
|
||||
...mockContext,
|
||||
input: { files: ['old.md'] },
|
||||
input: { files: ['old.md'] } as any,
|
||||
}),
|
||||
).rejects.toThrow(/each file must have a from and to property/);
|
||||
|
||||
await expect(
|
||||
action.handler({
|
||||
...mockContext,
|
||||
input: { files: [{ from: 'old.md' }] },
|
||||
input: { files: [{ from: 'old.md' }] } as any,
|
||||
}),
|
||||
).rejects.toThrow(/each file must have a from and to property/);
|
||||
|
||||
await expect(
|
||||
action.handler({
|
||||
...mockContext,
|
||||
input: { files: [{ to: 'new.md' }] },
|
||||
input: { files: [{ to: 'new.md' }] } as any,
|
||||
}),
|
||||
).rejects.toThrow(/each file must have a from and to property/);
|
||||
});
|
||||
|
||||
@@ -17,16 +17,16 @@ import { createTemplateAction } from '../../createTemplateAction';
|
||||
import { resolveSafeChildPath } from '@backstage/backend-common';
|
||||
|
||||
import { InputError } from '@backstage/errors';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import fs from 'fs-extra';
|
||||
|
||||
interface FilesToRename extends JsonObject {
|
||||
from: string;
|
||||
to: string;
|
||||
}
|
||||
|
||||
export const createFilesystemRenameAction = () => {
|
||||
return createTemplateAction<{ files: FilesToRename }>({
|
||||
return createTemplateAction<{
|
||||
files: Array<{
|
||||
from: string;
|
||||
to: string;
|
||||
overwrite?: boolean;
|
||||
}>;
|
||||
}>({
|
||||
id: 'fs:rename',
|
||||
description: 'Renames files and directories within the workspace',
|
||||
schema: {
|
||||
|
||||
@@ -23,8 +23,6 @@ import { OctokitProvider } from './OctokitProvider';
|
||||
import { emitterEventNames } from '@octokit/webhooks';
|
||||
import { assertError } from '@backstage/errors';
|
||||
|
||||
type ContentType = 'form' | 'json';
|
||||
|
||||
export function createGithubWebhookAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
defaultWebhookSecret?: string;
|
||||
@@ -45,7 +43,7 @@ export function createGithubWebhookAction(options: {
|
||||
webhookSecret?: string;
|
||||
events?: string[];
|
||||
active?: boolean;
|
||||
contentType?: ContentType;
|
||||
contentType?: 'form' | 'json';
|
||||
insecureSsl?: boolean;
|
||||
token?: string;
|
||||
}>({
|
||||
|
||||
@@ -51,7 +51,7 @@ describe('publish:bitbucket', () => {
|
||||
const mockContext = {
|
||||
input: {
|
||||
repoUrl: 'bitbucket.org?workspace=workspace&project=project&repo=repo',
|
||||
repoVisibility: 'private',
|
||||
repoVisibility: 'private' as const,
|
||||
},
|
||||
workspacePath: 'lol',
|
||||
logger: getVoidLogger(),
|
||||
|
||||
@@ -29,7 +29,7 @@ const createBitbucketCloudRepository = async (opts: {
|
||||
workspace: string;
|
||||
project: string;
|
||||
repo: string;
|
||||
description: string;
|
||||
description?: string;
|
||||
repoVisibility: 'private' | 'public';
|
||||
authorization: string;
|
||||
}) => {
|
||||
@@ -91,7 +91,7 @@ const createBitbucketServerRepository = async (opts: {
|
||||
host: string;
|
||||
project: string;
|
||||
repo: string;
|
||||
description: string;
|
||||
description?: string;
|
||||
repoVisibility: 'private' | 'public';
|
||||
authorization: string;
|
||||
apiBaseUrl?: string;
|
||||
@@ -200,11 +200,11 @@ export function createPublishBitbucketAction(options: {
|
||||
|
||||
return createTemplateAction<{
|
||||
repoUrl: string;
|
||||
description: string;
|
||||
description?: string;
|
||||
defaultBranch?: string;
|
||||
repoVisibility: 'private' | 'public';
|
||||
repoVisibility?: 'private' | 'public';
|
||||
sourcePath?: string;
|
||||
enableLFS: boolean;
|
||||
enableLFS?: boolean;
|
||||
token?: string;
|
||||
}>({
|
||||
id: 'publish:bitbucket',
|
||||
|
||||
@@ -52,7 +52,7 @@ describe('publish:github', () => {
|
||||
input: {
|
||||
repoUrl: 'github.com?repo=repo&owner=owner',
|
||||
description: 'description',
|
||||
repoVisibility: 'private',
|
||||
repoVisibility: 'private' as const,
|
||||
access: 'owner/blam',
|
||||
},
|
||||
workspacePath: 'lol',
|
||||
|
||||
@@ -28,9 +28,6 @@ import { Config } from '@backstage/config';
|
||||
import { OctokitProvider } from '../github/OctokitProvider';
|
||||
import { assertError } from '@backstage/errors';
|
||||
|
||||
type Permission = 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
|
||||
type Collaborator = { access: Permission; username: string };
|
||||
|
||||
export function createPublishGithubAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
config: Config;
|
||||
@@ -50,8 +47,11 @@ export function createPublishGithubAction(options: {
|
||||
defaultBranch?: string;
|
||||
sourcePath?: string;
|
||||
requireCodeOwnerReviews?: boolean;
|
||||
repoVisibility: 'private' | 'internal' | 'public';
|
||||
collaborators: Collaborator[];
|
||||
repoVisibility?: 'private' | 'internal' | 'public';
|
||||
collaborators?: Array<{
|
||||
username: string;
|
||||
access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
|
||||
}>;
|
||||
token?: string;
|
||||
topics?: string[];
|
||||
}>({
|
||||
|
||||
+6
-1
@@ -28,13 +28,18 @@ import { ActionContext, TemplateAction } from '../../types';
|
||||
import {
|
||||
ClientFactoryInput,
|
||||
createPublishGithubPullRequestAction,
|
||||
GithubPullRequestActionInput,
|
||||
PullRequestCreator,
|
||||
} from './githubPullRequest';
|
||||
|
||||
const root = os.platform() === 'win32' ? 'C:\\root' : '/root';
|
||||
const workspacePath = resolvePath(root, 'my-workspace');
|
||||
|
||||
type GithubPullRequestActionInput = ReturnType<
|
||||
typeof createPublishGithubPullRequestAction
|
||||
> extends TemplateAction<infer U>
|
||||
? U
|
||||
: never;
|
||||
|
||||
describe('createPublishGithubPullRequestAction', () => {
|
||||
let instance: TemplateAction<GithubPullRequestActionInput>;
|
||||
let fakeClient: PullRequestCreator;
|
||||
|
||||
+9
-11
@@ -48,16 +48,6 @@ export type PullRequestCreatorConstructor = (
|
||||
octokit: Octokit,
|
||||
) => PullRequestCreator;
|
||||
|
||||
export type GithubPullRequestActionInput = {
|
||||
title: string;
|
||||
branchName: string;
|
||||
description: string;
|
||||
repoUrl: string;
|
||||
targetPath?: string;
|
||||
sourcePath?: string;
|
||||
token?: string;
|
||||
};
|
||||
|
||||
export type ClientFactoryInput = {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
githubCredentialsProvider?: GithubCredentialsProvider;
|
||||
@@ -122,7 +112,15 @@ export const createPublishGithubPullRequestAction = ({
|
||||
githubCredentialsProvider,
|
||||
clientFactory = defaultClientFactory,
|
||||
}: CreateGithubPullRequestActionOptions) => {
|
||||
return createTemplateAction<GithubPullRequestActionInput>({
|
||||
return createTemplateAction<{
|
||||
title: string;
|
||||
branchName: string;
|
||||
description: string;
|
||||
repoUrl: string;
|
||||
targetPath?: string;
|
||||
sourcePath?: string;
|
||||
token?: string;
|
||||
}>({
|
||||
id: 'publish:github:pull-request',
|
||||
schema: {
|
||||
input: {
|
||||
|
||||
@@ -45,7 +45,7 @@ describe('publish:gitlab', () => {
|
||||
const mockContext = {
|
||||
input: {
|
||||
repoUrl: 'gitlab.com?repo=repo&owner=owner',
|
||||
repoVisibility: 'private',
|
||||
repoVisibility: 'private' as const,
|
||||
},
|
||||
workspacePath: 'lol',
|
||||
logger: getVoidLogger(),
|
||||
|
||||
@@ -31,7 +31,7 @@ export function createPublishGitlabAction(options: {
|
||||
return createTemplateAction<{
|
||||
repoUrl: string;
|
||||
defaultBranch?: string;
|
||||
repoVisibility: 'private' | 'internal' | 'public';
|
||||
repoVisibility?: 'private' | 'internal' | 'public';
|
||||
sourcePath?: string;
|
||||
token?: string;
|
||||
}>({
|
||||
|
||||
+9
-11
@@ -24,22 +24,20 @@ import { InputError } from '@backstage/errors';
|
||||
import { parseRepoUrl } from './util';
|
||||
import { resolveSafeChildPath } from '@backstage/backend-common';
|
||||
|
||||
export type GitlabMergeRequestActionInput = {
|
||||
projectid: string;
|
||||
repoUrl: string;
|
||||
title: string;
|
||||
description: string;
|
||||
branchName: string;
|
||||
targetPath: string;
|
||||
token?: string;
|
||||
};
|
||||
|
||||
export const createPublishGitlabMergeRequestAction = (options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
}) => {
|
||||
const { integrations } = options;
|
||||
|
||||
return createTemplateAction<GitlabMergeRequestActionInput>({
|
||||
return createTemplateAction<{
|
||||
projectid: string;
|
||||
repoUrl: string;
|
||||
title: string;
|
||||
description: string;
|
||||
branchName: string;
|
||||
targetPath: string;
|
||||
token?: string;
|
||||
}>({
|
||||
id: 'publish:gitlab:merge-request',
|
||||
schema: {
|
||||
input: {
|
||||
|
||||
@@ -14,11 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { InputBase, TemplateAction } from './types';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { TemplateAction } from './types';
|
||||
|
||||
export const createTemplateAction = <Input extends InputBase>(
|
||||
templateAction: TemplateAction<Input>,
|
||||
): TemplateAction<any> => {
|
||||
export const createTemplateAction = <TInput extends JsonObject>(
|
||||
templateAction: TemplateAction<TInput>,
|
||||
): TemplateAction<TInput> => {
|
||||
// TODO(blam): Can add some more validation here to validate the action later on
|
||||
return templateAction;
|
||||
};
|
||||
|
||||
@@ -20,11 +20,7 @@ import { JsonValue, JsonObject } from '@backstage/types';
|
||||
import { Schema } from 'jsonschema';
|
||||
import { TaskSecrets, TemplateMetadata } from '../tasks/types';
|
||||
|
||||
type PartialJsonObject = Partial<JsonObject>;
|
||||
type PartialJsonValue = PartialJsonObject | JsonValue | undefined;
|
||||
export type InputBase = Partial<{ [name: string]: PartialJsonValue }>;
|
||||
|
||||
export type ActionContext<Input extends InputBase> = {
|
||||
export type ActionContext<Input extends JsonObject> = {
|
||||
/**
|
||||
* Base URL for the location of the task spec, typically the url of the source entity file.
|
||||
*/
|
||||
@@ -51,7 +47,7 @@ export type ActionContext<Input extends InputBase> = {
|
||||
metadata?: TemplateMetadata;
|
||||
};
|
||||
|
||||
export type TemplateAction<Input extends InputBase> = {
|
||||
export type TemplateAction<Input extends JsonObject> = {
|
||||
id: string;
|
||||
description?: string;
|
||||
schema?: {
|
||||
|
||||
Reference in New Issue
Block a user