Improve type-check for scaffolder output parameters

If an action uses zod to define the actions output schema, it is now ensured that `ctx.output` is using only the defined properties

Signed-off-by: Andreas Berger <andreas@berger-ecommerce.com>
This commit is contained in:
Andreas Berger
2023-03-16 18:25:52 +01:00
committed by blam
parent 12f1a5feac
commit a7eb36c6e3
11 changed files with 567 additions and 438 deletions
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-scaffolder-backend': patch
'@backstage/plugin-scaffolder-node': patch
---
Improve type-check for scaffolder output parameters
@@ -16,12 +16,15 @@ export function createFetchCookiecutterAction(options: {
reader: UrlReader;
integrations: ScmIntegrations;
containerRunner?: ContainerRunner;
}): TemplateAction<{
url: string;
targetPath?: string | undefined;
values: JsonObject;
copyWithoutRender?: string[] | undefined;
extensions?: string[] | undefined;
imageName?: string | undefined;
}>;
}): TemplateAction<
{
url: string;
targetPath?: string | undefined;
values: JsonObject;
copyWithoutRender?: string[] | undefined;
extensions?: string[] | undefined;
imageName?: string | undefined;
},
undefined
>;
```
@@ -9,40 +9,49 @@ import { TemplateAction } from '@backstage/plugin-scaffolder-node';
// @public
export const createGitlabProjectAccessTokenAction: (options: {
integrations: ScmIntegrationRegistry;
}) => TemplateAction<{
repoUrl: string;
projectId: string | number;
name: string;
accessLevel: number;
scopes: string[];
token?: string | undefined;
}>;
}) => TemplateAction<
{
repoUrl: string;
projectId: string | number;
name: string;
accessLevel: number;
scopes: string[];
token?: string | undefined;
},
undefined
>;
// @public
export const createGitlabProjectDeployTokenAction: (options: {
integrations: ScmIntegrationRegistry;
}) => TemplateAction<{
repoUrl: string;
projectId: string | number;
name: string;
username: string;
scopes: string[];
token?: string | undefined;
}>;
}) => TemplateAction<
{
repoUrl: string;
projectId: string | number;
name: string;
username: string;
scopes: string[];
token?: string | undefined;
},
undefined
>;
// @public
export const createGitlabProjectVariableAction: (options: {
integrations: ScmIntegrationRegistry;
}) => TemplateAction<{
repoUrl: string;
projectId: string | number;
key: string;
value: string;
variableType: string;
variableProtected: boolean;
masked: boolean;
raw: boolean;
environmentScope: string;
token?: string | undefined;
}>;
}) => TemplateAction<
{
repoUrl: string;
projectId: string | number;
key: string;
value: string;
variableType: string;
variableProtected: boolean;
masked: boolean;
raw: boolean;
environmentScope: string;
token?: string | undefined;
},
undefined
>;
```
@@ -15,10 +15,13 @@ export function createFetchRailsAction(options: {
integrations: ScmIntegrations;
containerRunner: ContainerRunner;
allowedImageNames?: string[];
}): TemplateAction<{
url: string;
targetPath?: string | undefined;
values: JsonObject;
imageName?: string | undefined;
}>;
}): TemplateAction<
{
url: string;
targetPath?: string | undefined;
values: JsonObject;
imageName?: string | undefined;
},
undefined
>;
```
@@ -9,13 +9,16 @@ import { TemplateAction } from '@backstage/plugin-scaffolder-node';
// @public
export function createSentryCreateProjectAction(options: {
config: Config;
}): TemplateAction<{
organizationSlug: string;
teamSlug: string;
name: string;
slug?: string | undefined;
authToken?: string | undefined;
}>;
}): TemplateAction<
{
organizationSlug: string;
teamSlug: string;
name: string;
slug?: string | undefined;
authToken?: string | undefined;
},
undefined
>;
// (No @packageDocumentation comment for this package)
```
@@ -7,9 +7,12 @@ import { JsonObject } from '@backstage/types';
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
// @public
export function createRunYeomanAction(): TemplateAction<{
namespace: string;
args?: string[] | undefined;
options?: JsonObject | undefined;
}>;
export function createRunYeomanAction(): TemplateAction<
{
namespace: string;
args?: string[] | undefined;
options?: JsonObject | undefined;
},
undefined
>;
```
+404 -330
View File
@@ -78,49 +78,66 @@ export function createCatalogRegisterAction(options: {
repoContentsUrl: string;
catalogInfoPath?: string | undefined;
optional?: boolean | undefined;
}
},
undefined
>;
// @public
export function createCatalogWriteAction(): TemplateAction_2<{
entity: {} & {
[k: string]: unknown;
};
filePath?: string | undefined;
}>;
export function createCatalogWriteAction(): TemplateAction_2<
{
filePath?: string | undefined;
entity: {};
},
undefined
>;
// @public
export function createDebugLogAction(): TemplateAction_2<{
message?: string | undefined;
listWorkspace?: boolean | undefined;
}>;
export function createDebugLogAction(): TemplateAction_2<
{
message?: string | undefined;
listWorkspace?: boolean | undefined;
},
undefined
>;
// @public
export function createFetchCatalogEntityAction(options: {
catalogClient: CatalogApi;
}): TemplateAction_2<{
entityRef?: string | undefined;
entityRefs?: string[] | undefined;
optional?: boolean | undefined;
}>;
}): TemplateAction_2<
{
optional?: boolean | undefined;
entityRef?: string | undefined;
entityRefs?: string[] | undefined;
},
{
entities?: any[] | undefined;
entity?: any;
}
>;
// @public
export function createFetchPlainAction(options: {
reader: UrlReader;
integrations: ScmIntegrations;
}): TemplateAction_2<{
url: string;
targetPath?: string | undefined;
}>;
}): TemplateAction_2<
{
url: string;
targetPath?: string | undefined;
},
undefined
>;
// @public
export function createFetchPlainFileAction(options: {
reader: UrlReader;
integrations: ScmIntegrations;
}): TemplateAction_2<{
url: string;
targetPath: string;
}>;
}): TemplateAction_2<
{
url: string;
targetPath: string;
},
undefined
>;
// @public
export function createFetchTemplateAction(options: {
@@ -128,57 +145,72 @@ export function createFetchTemplateAction(options: {
integrations: ScmIntegrations;
additionalTemplateFilters?: Record<string, TemplateFilter>;
additionalTemplateGlobals?: Record<string, TemplateGlobal>;
}): TemplateAction_2<{
url: string;
targetPath?: string | undefined;
values: any;
templateFileExtension?: string | boolean | undefined;
copyWithoutRender?: string[] | undefined;
copyWithoutTemplating?: string[] | undefined;
cookiecutterCompat?: boolean | undefined;
replace?: boolean | undefined;
}>;
}): TemplateAction_2<
{
url: string;
targetPath?: string | undefined;
values: any;
templateFileExtension?: string | boolean | undefined;
copyWithoutRender?: string[] | undefined;
copyWithoutTemplating?: string[] | undefined;
cookiecutterCompat?: boolean | undefined;
replace?: boolean | undefined;
},
undefined
>;
// @public
export const createFilesystemDeleteAction: () => TemplateAction_2<{
files: string[];
}>;
export const createFilesystemDeleteAction: () => TemplateAction_2<
{
files: string[];
},
undefined
>;
// @public
export const createFilesystemRenameAction: () => TemplateAction_2<{
files: Array<{
from: string;
to: string;
overwrite?: boolean;
}>;
}>;
export const createFilesystemRenameAction: () => TemplateAction_2<
{
files: Array<{
from: string;
to: string;
overwrite?: boolean;
}>;
},
undefined
>;
// @public
export function createGithubActionsDispatchAction(options: {
integrations: ScmIntegrations;
githubCredentialsProvider?: GithubCredentialsProvider;
}): TemplateAction_2<{
repoUrl: string;
workflowId: string;
branchOrTagName: string;
workflowInputs?:
| {
[key: string]: string;
}
| undefined;
token?: string | undefined;
}>;
}): TemplateAction_2<
{
repoUrl: string;
workflowId: string;
branchOrTagName: string;
workflowInputs?:
| {
[key: string]: string;
}
| undefined;
token?: string | undefined;
},
undefined
>;
// @public
export function createGithubIssuesLabelAction(options: {
integrations: ScmIntegrationRegistry;
githubCredentialsProvider?: GithubCredentialsProvider;
}): TemplateAction_2<{
repoUrl: string;
number: number;
labels: string[];
token?: string | undefined;
}>;
}): TemplateAction_2<
{
repoUrl: string;
number: number;
labels: string[];
token?: string | undefined;
},
undefined
>;
// @public
export interface CreateGithubPullRequestActionOptions {
@@ -203,334 +235,373 @@ export type CreateGithubPullRequestClientFactoryInput = {
export function createGithubRepoCreateAction(options: {
integrations: ScmIntegrationRegistry;
githubCredentialsProvider?: GithubCredentialsProvider;
}): TemplateAction_2<{
repoUrl: string;
description?: string | undefined;
homepage?: string | undefined;
access?: string | undefined;
deleteBranchOnMerge?: boolean | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
allowRebaseMerge?: boolean | undefined;
allowSquashMerge?: boolean | undefined;
squashMergeCommitTitle?: 'PR_TITLE' | 'COMMIT_OR_PR_TITLE' | undefined;
squashMergeCommitMessage?:
| 'PR_BODY'
| 'COMMIT_MESSAGES'
| 'BLANK'
| undefined;
allowMergeCommit?: boolean | undefined;
allowAutoMerge?: boolean | undefined;
requireCodeOwnerReviews?: boolean | undefined;
bypassPullRequestAllowances?:
| {
users?: string[] | undefined;
teams?: string[] | undefined;
apps?: string[] | undefined;
}
| undefined;
requiredApprovingReviewCount?: number | undefined;
restrictions?:
| {
users: string[];
teams: string[];
apps?: string[] | undefined;
}
| undefined;
requiredStatusCheckContexts?: string[] | undefined;
requireBranchesToBeUpToDate?: boolean | undefined;
requiredConversationResolution?: boolean | undefined;
repoVisibility?: 'internal' | 'private' | 'public' | undefined;
collaborators?:
| (
| {
user: string;
access: string;
}
| {
team: string;
access: string;
}
| {
username: string;
access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
}
)[]
| undefined;
hasProjects?: boolean | undefined;
hasWiki?: boolean | undefined;
hasIssues?: boolean | undefined;
token?: string | undefined;
topics?: string[] | undefined;
requireCommitSigning?: boolean | undefined;
}>;
}): TemplateAction_2<
{
repoUrl: string;
description?: string | undefined;
homepage?: string | undefined;
access?: string | undefined;
deleteBranchOnMerge?: boolean | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
allowRebaseMerge?: boolean | undefined;
allowSquashMerge?: boolean | undefined;
squashMergeCommitTitle?: 'PR_TITLE' | 'COMMIT_OR_PR_TITLE' | undefined;
squashMergeCommitMessage?:
| 'PR_BODY'
| 'COMMIT_MESSAGES'
| 'BLANK'
| undefined;
allowMergeCommit?: boolean | undefined;
allowAutoMerge?: boolean | undefined;
requireCodeOwnerReviews?: boolean | undefined;
bypassPullRequestAllowances?:
| {
users?: string[] | undefined;
teams?: string[] | undefined;
apps?: string[] | undefined;
}
| undefined;
requiredApprovingReviewCount?: number | undefined;
restrictions?:
| {
users: string[];
teams: string[];
apps?: string[] | undefined;
}
| undefined;
requiredStatusCheckContexts?: string[] | undefined;
requireBranchesToBeUpToDate?: boolean | undefined;
requiredConversationResolution?: boolean | undefined;
repoVisibility?: 'internal' | 'private' | 'public' | undefined;
collaborators?:
| (
| {
user: string;
access: string;
}
| {
team: string;
access: string;
}
| {
username: string;
access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
}
)[]
| undefined;
hasProjects?: boolean | undefined;
hasWiki?: boolean | undefined;
hasIssues?: boolean | undefined;
token?: string | undefined;
topics?: string[] | undefined;
requireCommitSigning?: boolean | undefined;
},
undefined
>;
// @public
export function createGithubRepoPushAction(options: {
integrations: ScmIntegrationRegistry;
config: Config;
githubCredentialsProvider?: GithubCredentialsProvider;
}): TemplateAction_2<{
repoUrl: string;
description?: string | undefined;
defaultBranch?: string | undefined;
protectDefaultBranch?: boolean | undefined;
protectEnforceAdmins?: boolean | undefined;
gitCommitMessage?: string | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
requireCodeOwnerReviews?: boolean | undefined;
dismissStaleReviews?: boolean | undefined;
bypassPullRequestAllowances?:
| {
users?: string[];
teams?: string[];
apps?: string[];
}
| undefined;
requiredApprovingReviewCount?: number | undefined;
restrictions?:
| {
users: string[];
teams: string[];
apps?: string[];
}
| undefined;
requiredStatusCheckContexts?: string[] | undefined;
requireBranchesToBeUpToDate?: boolean | undefined;
requiredConversationResolution?: boolean | undefined;
sourcePath?: string | undefined;
token?: string | undefined;
requiredCommitSigning?: boolean | undefined;
}>;
}): TemplateAction_2<
{
repoUrl: string;
description?: string | undefined;
defaultBranch?: string | undefined;
protectDefaultBranch?: boolean | undefined;
protectEnforceAdmins?: boolean | undefined;
gitCommitMessage?: string | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
requireCodeOwnerReviews?: boolean | undefined;
dismissStaleReviews?: boolean | undefined;
bypassPullRequestAllowances?:
| {
users?: string[];
teams?: string[];
apps?: string[];
}
| undefined;
requiredApprovingReviewCount?: number | undefined;
restrictions?:
| {
users: string[];
teams: string[];
apps?: string[];
}
| undefined;
requiredStatusCheckContexts?: string[] | undefined;
requireBranchesToBeUpToDate?: boolean | undefined;
requiredConversationResolution?: boolean | undefined;
sourcePath?: string | undefined;
token?: string | undefined;
requiredCommitSigning?: boolean | undefined;
},
undefined
>;
// @public
export function createGithubWebhookAction(options: {
integrations: ScmIntegrationRegistry;
defaultWebhookSecret?: string;
githubCredentialsProvider?: GithubCredentialsProvider;
}): TemplateAction_2<{
repoUrl: string;
webhookUrl: string;
webhookSecret?: string | undefined;
events?: string[] | undefined;
active?: boolean | undefined;
contentType?: 'form' | 'json' | undefined;
insecureSsl?: boolean | undefined;
token?: string | undefined;
}>;
}): TemplateAction_2<
{
repoUrl: string;
webhookUrl: string;
webhookSecret?: string | undefined;
events?: string[] | undefined;
active?: boolean | undefined;
contentType?: 'form' | 'json' | undefined;
insecureSsl?: boolean | undefined;
token?: string | undefined;
},
undefined
>;
// @public
export function createPublishAzureAction(options: {
integrations: ScmIntegrationRegistry;
config: Config;
}): TemplateAction_2<{
repoUrl: string;
description?: string | undefined;
defaultBranch?: string | undefined;
sourcePath?: string | undefined;
token?: string | undefined;
gitCommitMessage?: string | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
}>;
}): TemplateAction_2<
{
repoUrl: string;
description?: string | undefined;
defaultBranch?: string | undefined;
sourcePath?: string | undefined;
token?: string | undefined;
gitCommitMessage?: string | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
},
undefined
>;
// @public @deprecated
export function createPublishBitbucketAction(options: {
integrations: ScmIntegrationRegistry;
config: Config;
}): TemplateAction_2<{
repoUrl: string;
description?: string | undefined;
defaultBranch?: string | undefined;
repoVisibility?: 'private' | 'public' | undefined;
sourcePath?: string | undefined;
enableLFS?: boolean | undefined;
token?: string | undefined;
gitCommitMessage?: string | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
}>;
}): TemplateAction_2<
{
repoUrl: string;
description?: string | undefined;
defaultBranch?: string | undefined;
repoVisibility?: 'private' | 'public' | undefined;
sourcePath?: string | undefined;
enableLFS?: boolean | undefined;
token?: string | undefined;
gitCommitMessage?: string | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
},
undefined
>;
// @public
export function createPublishBitbucketCloudAction(options: {
integrations: ScmIntegrationRegistry;
config: Config;
}): TemplateAction_2<{
repoUrl: string;
description?: string | undefined;
defaultBranch?: string | undefined;
repoVisibility?: 'private' | 'public' | undefined;
sourcePath?: string | undefined;
token?: string | undefined;
}>;
}): TemplateAction_2<
{
repoUrl: string;
description?: string | undefined;
defaultBranch?: string | undefined;
repoVisibility?: 'private' | 'public' | undefined;
sourcePath?: string | undefined;
token?: string | undefined;
},
undefined
>;
// @public
export function createPublishBitbucketServerAction(options: {
integrations: ScmIntegrationRegistry;
config: Config;
}): TemplateAction_2<{
repoUrl: string;
description?: string | undefined;
defaultBranch?: string | undefined;
repoVisibility?: 'private' | 'public' | undefined;
sourcePath?: string | undefined;
enableLFS?: boolean | undefined;
token?: string | undefined;
gitCommitMessage?: string | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
}>;
}): TemplateAction_2<
{
repoUrl: string;
description?: string | undefined;
defaultBranch?: string | undefined;
repoVisibility?: 'private' | 'public' | undefined;
sourcePath?: string | undefined;
enableLFS?: boolean | undefined;
token?: string | undefined;
gitCommitMessage?: string | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
},
undefined
>;
// @public
export function createPublishGerritAction(options: {
integrations: ScmIntegrationRegistry;
config: Config;
}): TemplateAction_2<{
repoUrl: string;
description: string;
defaultBranch?: string | undefined;
gitCommitMessage?: string | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
sourcePath?: string | undefined;
}>;
}): TemplateAction_2<
{
repoUrl: string;
description: string;
defaultBranch?: string | undefined;
gitCommitMessage?: string | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
sourcePath?: string | undefined;
},
undefined
>;
// @public
export function createPublishGerritReviewAction(options: {
integrations: ScmIntegrationRegistry;
config: Config;
}): TemplateAction_2<{
repoUrl: string;
branch?: string | undefined;
sourcePath?: string | undefined;
gitCommitMessage?: string | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
}>;
}): TemplateAction_2<
{
repoUrl: string;
branch?: string | undefined;
sourcePath?: string | undefined;
gitCommitMessage?: string | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
},
undefined
>;
// @public
export function createPublishGithubAction(options: {
integrations: ScmIntegrationRegistry;
config: Config;
githubCredentialsProvider?: GithubCredentialsProvider;
}): TemplateAction_2<{
repoUrl: string;
description?: string | undefined;
homepage?: string | undefined;
access?: string | undefined;
defaultBranch?: string | undefined;
protectDefaultBranch?: boolean | undefined;
protectEnforceAdmins?: boolean | undefined;
deleteBranchOnMerge?: boolean | undefined;
gitCommitMessage?: string | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
allowRebaseMerge?: boolean | undefined;
allowSquashMerge?: boolean | undefined;
squashMergeCommitTitle?: 'PR_TITLE' | 'COMMIT_OR_PR_TITLE' | undefined;
squashMergeCommitMessage?:
| 'PR_BODY'
| 'COMMIT_MESSAGES'
| 'BLANK'
| undefined;
allowMergeCommit?: boolean | undefined;
allowAutoMerge?: boolean | undefined;
sourcePath?: string | undefined;
bypassPullRequestAllowances?:
| {
users?: string[];
teams?: string[];
apps?: string[];
}
| undefined;
requiredApprovingReviewCount?: number | undefined;
restrictions?:
| {
users: string[];
teams: string[];
apps?: string[];
}
| undefined;
requireCodeOwnerReviews?: boolean | undefined;
dismissStaleReviews?: boolean | undefined;
requiredStatusCheckContexts?: string[] | undefined;
requireBranchesToBeUpToDate?: boolean | undefined;
requiredConversationResolution?: boolean | undefined;
repoVisibility?: 'internal' | 'private' | 'public' | undefined;
collaborators?:
| (
| {
user: string;
access: string;
}
| {
team: string;
access: string;
}
| {
username: string;
access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
}
)[]
| undefined;
hasProjects?: boolean | undefined;
hasWiki?: boolean | undefined;
hasIssues?: boolean | undefined;
token?: string | undefined;
topics?: string[] | undefined;
requiredCommitSigning?: boolean | undefined;
}>;
}): TemplateAction_2<
{
repoUrl: string;
description?: string | undefined;
homepage?: string | undefined;
access?: string | undefined;
defaultBranch?: string | undefined;
protectDefaultBranch?: boolean | undefined;
protectEnforceAdmins?: boolean | undefined;
deleteBranchOnMerge?: boolean | undefined;
gitCommitMessage?: string | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
allowRebaseMerge?: boolean | undefined;
allowSquashMerge?: boolean | undefined;
squashMergeCommitTitle?: 'PR_TITLE' | 'COMMIT_OR_PR_TITLE' | undefined;
squashMergeCommitMessage?:
| 'PR_BODY'
| 'COMMIT_MESSAGES'
| 'BLANK'
| undefined;
allowMergeCommit?: boolean | undefined;
allowAutoMerge?: boolean | undefined;
sourcePath?: string | undefined;
bypassPullRequestAllowances?:
| {
users?: string[];
teams?: string[];
apps?: string[];
}
| undefined;
requiredApprovingReviewCount?: number | undefined;
restrictions?:
| {
users: string[];
teams: string[];
apps?: string[];
}
| undefined;
requireCodeOwnerReviews?: boolean | undefined;
dismissStaleReviews?: boolean | undefined;
requiredStatusCheckContexts?: string[] | undefined;
requireBranchesToBeUpToDate?: boolean | undefined;
requiredConversationResolution?: boolean | undefined;
repoVisibility?: 'internal' | 'private' | 'public' | undefined;
collaborators?:
| (
| {
user: string;
access: string;
}
| {
team: string;
access: string;
}
| {
username: string;
access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
}
)[]
| undefined;
hasProjects?: boolean | undefined;
hasWiki?: boolean | undefined;
hasIssues?: boolean | undefined;
token?: string | undefined;
topics?: string[] | undefined;
requiredCommitSigning?: boolean | undefined;
},
undefined
>;
// @public
export const createPublishGithubPullRequestAction: (
options: CreateGithubPullRequestActionOptions,
) => TemplateAction_2<{
title: string;
branchName: string;
description: string;
repoUrl: string;
draft?: boolean | undefined;
targetPath?: string | undefined;
sourcePath?: string | undefined;
token?: string | undefined;
reviewers?: string[] | undefined;
teamReviewers?: string[] | undefined;
}>;
) => TemplateAction_2<
{
title: string;
branchName: string;
description: string;
repoUrl: string;
draft?: boolean | undefined;
targetPath?: string | undefined;
sourcePath?: string | undefined;
token?: string | undefined;
reviewers?: string[] | undefined;
teamReviewers?: string[] | undefined;
},
undefined
>;
// @public
export function createPublishGitlabAction(options: {
integrations: ScmIntegrationRegistry;
config: Config;
}): TemplateAction_2<{
repoUrl: string;
defaultBranch?: string | undefined;
repoVisibility?: 'internal' | 'private' | 'public' | undefined;
sourcePath?: string | undefined;
token?: string | undefined;
gitCommitMessage?: string | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
setUserAsOwner?: boolean | undefined;
topics?: string[] | undefined;
}>;
}): TemplateAction_2<
{
repoUrl: string;
defaultBranch?: string | undefined;
repoVisibility?: 'internal' | 'private' | 'public' | undefined;
sourcePath?: string | undefined;
token?: string | undefined;
gitCommitMessage?: string | undefined;
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
setUserAsOwner?: boolean | undefined;
topics?: string[] | undefined;
},
undefined
>;
// @public
export const createPublishGitlabMergeRequestAction: (options: {
integrations: ScmIntegrationRegistry;
}) => TemplateAction_2<{
repoUrl: string;
title: string;
description: string;
branchName: string;
sourcePath?: string | undefined;
targetPath?: string | undefined;
token?: string | undefined;
commitAction?: 'update' | 'delete' | 'create' | undefined;
projectid?: string | undefined;
removeSourceBranch?: boolean | undefined;
assignee?: string | undefined;
}>;
}) => TemplateAction_2<
{
repoUrl: string;
title: string;
description: string;
branchName: string;
sourcePath?: string | undefined;
targetPath?: string | undefined;
token?: string | undefined;
commitAction?: 'update' | 'delete' | 'create' | undefined;
projectid?: string | undefined;
removeSourceBranch?: boolean | undefined;
assignee?: string | undefined;
},
undefined
>;
// @public
export function createRouter(options: RouterOptions): Promise<express.Router>;
@@ -543,14 +614,17 @@ export const createTemplateAction: <
TActionInput = TInputSchema extends ZodType<any, any, infer IReturn>
? IReturn
: TParams,
TActionOutput = TOutputSchema extends ZodType<any, any, infer IReturn_1>
? IReturn_1
: undefined,
>(
action: TemplateActionOptions<TActionInput, TInputSchema, TOutputSchema>,
) => TemplateAction_2<TActionInput>;
) => TemplateAction_2<TActionInput, TActionOutput>;
// @public
export function createWaitAction(options?: {
maxWaitTime?: Duration | HumanDuration;
}): TemplateAction_2<HumanDuration>;
}): TemplateAction_2<HumanDuration, undefined>;
// @public
export type CreateWorkerOptions = {
@@ -17,6 +17,7 @@
import { CatalogApi } from '@backstage/catalog-client';
import { createTemplateAction } from '@backstage/plugin-scaffolder-node';
import yaml from 'yaml';
import { z } from 'zod';
const id = 'catalog:fetch';
@@ -63,55 +64,46 @@ export function createFetchCatalogEntityAction(options: {
}) {
const { catalogClient } = options;
return createTemplateAction<{
entityRef?: string;
entityRefs?: string[];
optional?: boolean;
}>({
return createTemplateAction({
id,
description:
'Returns entity or entities from the catalog by entity reference(s)',
examples,
schema: {
input: {
type: 'object',
properties: {
entityRef: {
type: 'string',
title: 'Entity reference',
input: z.object({
entityRef: z
.string({
description: 'Entity reference of the entity to get',
},
entityRefs: {
type: 'array',
title: 'Entity references',
})
.optional(),
entityRefs: z
.array(z.string(), {
description: 'Entity references of the entities to get',
},
optional: {
title: 'Optional',
})
.optional(),
optional: z
.boolean({
description:
'Allow the entity or entities to optionally exist. Default: false',
type: 'boolean',
},
},
},
output: {
type: 'object',
properties: {
entity: {
title: 'Entity found by the entity reference',
type: 'object',
})
.optional(),
}),
output: z.object({
entity: z
.any({
description:
'Object containing same values used in the Entity schema. Only when used with `entityRef` parameter.',
},
entities: {
title: 'Entities found by the entity references',
type: 'array',
items: { type: 'object' },
description:
'Array containing objects with same values used in the Entity schema. Only when used with `entityRefs` parameter.',
},
},
},
})
.optional(),
entities: z
.array(
z.any({
description:
'Array containing objects with same values used in the Entity schema. Only when used with `entityRefs` parameter.',
}),
)
.optional(),
}),
},
async handler(ctx) {
const { entityRef, entityRefs, optional } = ctx.input;
+25 -6
View File
@@ -16,13 +16,19 @@ import { Writable } from 'stream';
import { z } from 'zod';
// @public
export type ActionContext<TActionInput extends JsonObject> = {
export type ActionContext<
TActionInput extends JsonObject,
TActionOutput extends JsonObject | undefined = undefined,
> = {
logger: Logger;
logStream: Writable;
secrets?: TaskSecrets;
workspacePath: string;
input: TActionInput;
output(name: string, value: JsonValue): void;
output<KEY extends keyof TActionOutput>(
name: TActionOutput extends undefined ? string : KEY,
value: TActionOutput extends undefined ? JsonValue : TActionOutput[KEY],
): void;
createTemporaryDirectory(): Promise<string>;
templateInfo?: TemplateInfo;
isDryRun?: boolean;
@@ -41,9 +47,12 @@ export const createTemplateAction: <
TActionInput = TInputSchema extends z.ZodType<any, any, infer IReturn>
? IReturn
: TParams,
TActionOutput = TOutputSchema extends z.ZodType<any, any, infer IReturn_1>
? IReturn_1
: undefined,
>(
action: TemplateActionOptions<TActionInput, TInputSchema, TOutputSchema>,
) => TemplateAction<TActionInput>;
) => TemplateAction<TActionInput, TActionOutput>;
// @alpha
export interface ScaffolderActionsExtensionPoint {
@@ -60,7 +69,10 @@ export type TaskSecrets = Record<string, string> & {
};
// @public (undocumented)
export type TemplateAction<TActionInput = unknown> = {
export type TemplateAction<
TActionInput = unknown,
TActionOutput = undefined,
> = {
id: string;
description?: string;
examples?: {
@@ -72,7 +84,7 @@ export type TemplateAction<TActionInput = unknown> = {
input?: Schema;
output?: Schema;
};
handler: (ctx: ActionContext<TActionInput>) => Promise<void>;
handler: (ctx: ActionContext<TActionInput, TActionOutput>) => Promise<void>;
};
// @public (undocumented)
@@ -92,6 +104,13 @@ export type TemplateActionOptions<
input?: TInputSchema;
output?: TOutputSchema;
};
handler: (ctx: ActionContext<TActionInput>) => Promise<void>;
handler: (
ctx: ActionContext<
TActionInput,
TOutputSchema extends z.ZodType<any, any, infer IReturn>
? IReturn
: undefined
>,
) => Promise<void>;
};
```
@@ -33,7 +33,14 @@ export type TemplateActionOptions<
input?: TInputSchema;
output?: TOutputSchema;
};
handler: (ctx: ActionContext<TActionInput>) => Promise<void>;
handler: (
ctx: ActionContext<
TActionInput,
TOutputSchema extends z.ZodType<any, any, infer IReturn>
? IReturn
: undefined
>,
) => Promise<void>;
};
/**
@@ -48,9 +55,12 @@ export const createTemplateAction = <
TActionInput = TInputSchema extends z.ZodType<any, any, infer IReturn>
? IReturn
: TParams,
TActionOutput = TOutputSchema extends z.ZodType<any, any, infer IReturn>
? IReturn
: undefined,
>(
action: TemplateActionOptions<TActionInput, TInputSchema, TOutputSchema>,
): TemplateAction<TActionInput> => {
): TemplateAction<TActionInput, TActionOutput> => {
const inputSchema =
action.schema?.input && 'safeParseAsync' in action.schema.input
? zodToJsonSchema(action.schema.input)
@@ -61,7 +71,7 @@ export const createTemplateAction = <
? zodToJsonSchema(action.schema.output)
: action.schema?.output;
const templateAction = {
return {
...action,
schema: {
...action.schema,
@@ -69,6 +79,4 @@ export const createTemplateAction = <
output: outputSchema,
},
};
return templateAction;
};
+14 -5
View File
@@ -17,7 +17,7 @@
import { Logger } from 'winston';
import { Writable } from 'stream';
import { JsonObject, JsonValue } from '@backstage/types';
import { TaskSecrets } from '../tasks/types';
import { TaskSecrets } from '../tasks';
import { TemplateInfo } from '@backstage/plugin-scaffolder-common';
import { UserEntity } from '@backstage/catalog-model';
import { Schema } from 'jsonschema';
@@ -26,13 +26,19 @@ import { Schema } from 'jsonschema';
* ActionContext is passed into scaffolder actions.
* @public
*/
export type ActionContext<TActionInput extends JsonObject> = {
export type ActionContext<
TActionInput extends JsonObject,
TActionOutput extends JsonObject | undefined = undefined,
> = {
logger: Logger;
logStream: Writable;
secrets?: TaskSecrets;
workspacePath: string;
input: TActionInput;
output(name: string, value: JsonValue): void;
output<KEY extends keyof TActionOutput>(
name: TActionOutput extends undefined ? string : KEY,
value: TActionOutput extends undefined ? JsonValue : TActionOutput[KEY],
): void;
/**
* Creates a temporary directory for use by the action, which is then cleaned up automatically.
@@ -68,7 +74,10 @@ export type ActionContext<TActionInput extends JsonObject> = {
};
/** @public */
export type TemplateAction<TActionInput = unknown> = {
export type TemplateAction<
TActionInput = unknown,
TActionOutput = undefined,
> = {
id: string;
description?: string;
examples?: { description: string; example: string }[];
@@ -77,5 +86,5 @@ export type TemplateAction<TActionInput = unknown> = {
input?: Schema;
output?: Schema;
};
handler: (ctx: ActionContext<TActionInput>) => Promise<void>;
handler: (ctx: ActionContext<TActionInput, TActionOutput>) => Promise<void>;
};