scaffolder-backend: update TemplateAction to use more precise types

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2022-02-15 17:54:45 +01:00
parent 80c627d098
commit 661594bf43
26 changed files with 257 additions and 128 deletions
+5
View File
@@ -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.
+7
View File
@@ -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;
}>;
```
+132 -32
View File
@@ -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[];
}>({
@@ -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;
@@ -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;
}>({
@@ -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?: {