@backstage/plugin-scaffolder-backend 1.4.0-next.1 → 1.4.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/dist/index.cjs.js +818 -658
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +75 -14
- package/package.json +10 -10
package/dist/index.cjs.js
CHANGED
|
@@ -12,16 +12,16 @@ var path = require('path');
|
|
|
12
12
|
var globby = require('globby');
|
|
13
13
|
var isbinaryfile = require('isbinaryfile');
|
|
14
14
|
var vm2 = require('vm2');
|
|
15
|
+
var octokit = require('octokit');
|
|
15
16
|
var child_process = require('child_process');
|
|
16
17
|
var stream = require('stream');
|
|
18
|
+
var webhooks = require('@octokit/webhooks');
|
|
17
19
|
var azureDevopsNodeApi = require('azure-devops-node-api');
|
|
18
20
|
var fetch = require('node-fetch');
|
|
19
21
|
var crypto = require('crypto');
|
|
20
|
-
var octokit = require('octokit');
|
|
21
22
|
var octokitPluginCreatePullRequest = require('octokit-plugin-create-pull-request');
|
|
22
23
|
var limiterFactory = require('p-limit');
|
|
23
24
|
var node = require('@gitbeaker/node');
|
|
24
|
-
var webhooks = require('@octokit/webhooks');
|
|
25
25
|
var uuid = require('uuid');
|
|
26
26
|
var luxon = require('luxon');
|
|
27
27
|
var ObservableImpl = require('zen-observable');
|
|
@@ -688,6 +688,55 @@ const createFilesystemRenameAction = () => {
|
|
|
688
688
|
});
|
|
689
689
|
};
|
|
690
690
|
|
|
691
|
+
const getRepoSourceDirectory = (workspacePath, sourcePath) => {
|
|
692
|
+
if (sourcePath) {
|
|
693
|
+
const safeSuffix = path.normalize(sourcePath).replace(/^(\.\.(\/|\\|$))+/, "");
|
|
694
|
+
const path$1 = path.join(workspacePath, safeSuffix);
|
|
695
|
+
if (!backendCommon.isChildPath(workspacePath, path$1)) {
|
|
696
|
+
throw new Error("Invalid source path");
|
|
697
|
+
}
|
|
698
|
+
return path$1;
|
|
699
|
+
}
|
|
700
|
+
return workspacePath;
|
|
701
|
+
};
|
|
702
|
+
const parseRepoUrl = (repoUrl, integrations) => {
|
|
703
|
+
var _a, _b, _c, _d, _e;
|
|
704
|
+
let parsed;
|
|
705
|
+
try {
|
|
706
|
+
parsed = new URL(`https://${repoUrl}`);
|
|
707
|
+
} catch (error) {
|
|
708
|
+
throw new errors.InputError(`Invalid repo URL passed to publisher, got ${repoUrl}, ${error}`);
|
|
709
|
+
}
|
|
710
|
+
const host = parsed.host;
|
|
711
|
+
const owner = (_a = parsed.searchParams.get("owner")) != null ? _a : void 0;
|
|
712
|
+
const organization = (_b = parsed.searchParams.get("organization")) != null ? _b : void 0;
|
|
713
|
+
const workspace = (_c = parsed.searchParams.get("workspace")) != null ? _c : void 0;
|
|
714
|
+
const project = (_d = parsed.searchParams.get("project")) != null ? _d : void 0;
|
|
715
|
+
const type = (_e = integrations.byHost(host)) == null ? void 0 : _e.type;
|
|
716
|
+
if (!type) {
|
|
717
|
+
throw new errors.InputError(`No matching integration configuration for host ${host}, please check your integrations config`);
|
|
718
|
+
}
|
|
719
|
+
if (type === "bitbucket") {
|
|
720
|
+
if (host === "bitbucket.org") {
|
|
721
|
+
if (!workspace) {
|
|
722
|
+
throw new errors.InputError(`Invalid repo URL passed to publisher: ${repoUrl}, missing workspace`);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
if (!project) {
|
|
726
|
+
throw new errors.InputError(`Invalid repo URL passed to publisher: ${repoUrl}, missing project`);
|
|
727
|
+
}
|
|
728
|
+
} else {
|
|
729
|
+
if (!owner) {
|
|
730
|
+
throw new errors.InputError(`Invalid repo URL passed to publisher: ${repoUrl}, missing owner`);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
const repo = parsed.searchParams.get("repo");
|
|
734
|
+
if (!repo) {
|
|
735
|
+
throw new errors.InputError(`Invalid repo URL passed to publisher: ${repoUrl}, missing repo`);
|
|
736
|
+
}
|
|
737
|
+
return { host, owner, repo, organization, workspace, project };
|
|
738
|
+
};
|
|
739
|
+
|
|
691
740
|
const executeShellCommand = async (options) => {
|
|
692
741
|
const {
|
|
693
742
|
command,
|
|
@@ -803,138 +852,762 @@ const enableBranchProtectionOnDefaultRepoBranch = async ({
|
|
|
803
852
|
}
|
|
804
853
|
};
|
|
805
854
|
|
|
806
|
-
const
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
855
|
+
const DEFAULT_TIMEOUT_MS = 6e4;
|
|
856
|
+
async function getOctokitOptions(options) {
|
|
857
|
+
var _a;
|
|
858
|
+
const { integrations, credentialsProvider, repoUrl, token } = options;
|
|
859
|
+
const { owner, repo, host } = parseRepoUrl(repoUrl, integrations);
|
|
860
|
+
const requestOptions = {
|
|
861
|
+
timeout: DEFAULT_TIMEOUT_MS
|
|
862
|
+
};
|
|
863
|
+
if (!owner) {
|
|
864
|
+
throw new errors.InputError(`No owner provided for repo ${repoUrl}`);
|
|
814
865
|
}
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
866
|
+
const integrationConfig = (_a = integrations.github.byHost(host)) == null ? void 0 : _a.config;
|
|
867
|
+
if (!integrationConfig) {
|
|
868
|
+
throw new errors.InputError(`No integration for host ${host}`);
|
|
869
|
+
}
|
|
870
|
+
if (token) {
|
|
871
|
+
return {
|
|
872
|
+
auth: token,
|
|
873
|
+
baseUrl: integrationConfig.apiBaseUrl,
|
|
874
|
+
previews: ["nebula-preview"],
|
|
875
|
+
request: requestOptions
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
const githubCredentialsProvider = credentialsProvider != null ? credentialsProvider : integration.DefaultGithubCredentialsProvider.fromIntegrations(integrations);
|
|
879
|
+
const { token: credentialProviderToken } = await githubCredentialsProvider.getCredentials({
|
|
880
|
+
url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`
|
|
881
|
+
});
|
|
882
|
+
if (!credentialProviderToken) {
|
|
883
|
+
throw new errors.InputError(`No token available for host: ${host}, with owner ${owner}, and repo ${repo}`);
|
|
884
|
+
}
|
|
885
|
+
return {
|
|
886
|
+
auth: credentialProviderToken,
|
|
887
|
+
baseUrl: integrationConfig.apiBaseUrl,
|
|
888
|
+
previews: ["nebula-preview"]
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
async function createGithubRepoWithCollaboratorsAndTopics(client, repo, owner, repoVisibility, description, deleteBranchOnMerge, allowMergeCommit, allowSquashMerge, allowRebaseMerge, access, collaborators, topics, logger) {
|
|
892
|
+
const user = await client.rest.users.getByUsername({
|
|
893
|
+
username: owner
|
|
894
|
+
});
|
|
895
|
+
const repoCreationPromise = user.data.type === "Organization" ? client.rest.repos.createInOrg({
|
|
896
|
+
name: repo,
|
|
897
|
+
org: owner,
|
|
898
|
+
private: repoVisibility === "private",
|
|
899
|
+
visibility: repoVisibility,
|
|
900
|
+
description,
|
|
901
|
+
delete_branch_on_merge: deleteBranchOnMerge,
|
|
902
|
+
allow_merge_commit: allowMergeCommit,
|
|
903
|
+
allow_squash_merge: allowSquashMerge,
|
|
904
|
+
allow_rebase_merge: allowRebaseMerge
|
|
905
|
+
}) : client.rest.repos.createForAuthenticatedUser({
|
|
906
|
+
name: repo,
|
|
907
|
+
private: repoVisibility === "private",
|
|
908
|
+
description,
|
|
909
|
+
delete_branch_on_merge: deleteBranchOnMerge,
|
|
910
|
+
allow_merge_commit: allowMergeCommit,
|
|
911
|
+
allow_squash_merge: allowSquashMerge,
|
|
912
|
+
allow_rebase_merge: allowRebaseMerge
|
|
913
|
+
});
|
|
914
|
+
let newRepo;
|
|
820
915
|
try {
|
|
821
|
-
|
|
822
|
-
} catch (
|
|
823
|
-
|
|
916
|
+
newRepo = (await repoCreationPromise).data;
|
|
917
|
+
} catch (e) {
|
|
918
|
+
errors.assertError(e);
|
|
919
|
+
if (e.message === "Resource not accessible by integration") {
|
|
920
|
+
logger.warn(`The GitHub app or token provided may not have the required permissions to create the ${user.data.type} repository ${owner}/${repo}.`);
|
|
921
|
+
}
|
|
922
|
+
throw new Error(`Failed to create the ${user.data.type} repository ${owner}/${repo}, ${e.message}`);
|
|
824
923
|
}
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
924
|
+
if (access == null ? void 0 : access.startsWith(`${owner}/`)) {
|
|
925
|
+
const [, team] = access.split("/");
|
|
926
|
+
await client.rest.teams.addOrUpdateRepoPermissionsInOrg({
|
|
927
|
+
org: owner,
|
|
928
|
+
team_slug: team,
|
|
929
|
+
owner,
|
|
930
|
+
repo,
|
|
931
|
+
permission: "admin"
|
|
932
|
+
});
|
|
933
|
+
} else if (access && access !== owner) {
|
|
934
|
+
await client.rest.repos.addCollaborator({
|
|
935
|
+
owner,
|
|
936
|
+
repo,
|
|
937
|
+
username: access,
|
|
938
|
+
permission: "admin"
|
|
939
|
+
});
|
|
833
940
|
}
|
|
834
|
-
if (
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
941
|
+
if (collaborators) {
|
|
942
|
+
for (const collaborator of collaborators) {
|
|
943
|
+
try {
|
|
944
|
+
if ("user" in collaborator) {
|
|
945
|
+
await client.rest.repos.addCollaborator({
|
|
946
|
+
owner,
|
|
947
|
+
repo,
|
|
948
|
+
username: collaborator.user,
|
|
949
|
+
permission: collaborator.access
|
|
950
|
+
});
|
|
951
|
+
} else if ("team" in collaborator) {
|
|
952
|
+
await client.rest.teams.addOrUpdateRepoPermissionsInOrg({
|
|
953
|
+
org: owner,
|
|
954
|
+
team_slug: collaborator.team,
|
|
955
|
+
owner,
|
|
956
|
+
repo,
|
|
957
|
+
permission: collaborator.access
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
} catch (e) {
|
|
961
|
+
errors.assertError(e);
|
|
962
|
+
const name = extractCollaboratorName(collaborator);
|
|
963
|
+
logger.warn(`Skipping ${collaborator.access} access for ${name}, ${e.message}`);
|
|
838
964
|
}
|
|
839
965
|
}
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
966
|
+
}
|
|
967
|
+
if (topics) {
|
|
968
|
+
try {
|
|
969
|
+
await client.rest.repos.replaceAllTopics({
|
|
970
|
+
owner,
|
|
971
|
+
repo,
|
|
972
|
+
names: topics.map((t) => t.toLowerCase())
|
|
973
|
+
});
|
|
974
|
+
} catch (e) {
|
|
975
|
+
errors.assertError(e);
|
|
976
|
+
logger.warn(`Skipping topics ${topics.join(" ")}, ${e.message}`);
|
|
846
977
|
}
|
|
847
978
|
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
979
|
+
return newRepo;
|
|
980
|
+
}
|
|
981
|
+
async function initRepoPushAndProtect(remoteUrl, password, workspacePath, sourcePath, defaultBranch, protectDefaultBranch, owner, client, repo, requireCodeOwnerReviews, requiredStatusCheckContexts, config, logger, gitCommitMessage, gitAuthorName, gitAuthorEmail) {
|
|
982
|
+
const gitAuthorInfo = {
|
|
983
|
+
name: gitAuthorName ? gitAuthorName : config.getOptionalString("scaffolder.defaultAuthor.name"),
|
|
984
|
+
email: gitAuthorEmail ? gitAuthorEmail : config.getOptionalString("scaffolder.defaultAuthor.email")
|
|
985
|
+
};
|
|
986
|
+
const commitMessage = gitCommitMessage ? gitCommitMessage : config.getOptionalString("scaffolder.defaultCommitMessage");
|
|
987
|
+
await initRepoAndPush({
|
|
988
|
+
dir: getRepoSourceDirectory(workspacePath, sourcePath),
|
|
989
|
+
remoteUrl,
|
|
990
|
+
defaultBranch,
|
|
991
|
+
auth: {
|
|
992
|
+
username: "x-access-token",
|
|
993
|
+
password
|
|
994
|
+
},
|
|
995
|
+
logger,
|
|
996
|
+
commitMessage,
|
|
997
|
+
gitAuthorInfo
|
|
998
|
+
});
|
|
999
|
+
if (protectDefaultBranch) {
|
|
1000
|
+
try {
|
|
1001
|
+
await enableBranchProtectionOnDefaultRepoBranch({
|
|
1002
|
+
owner,
|
|
1003
|
+
client,
|
|
1004
|
+
repoName: repo,
|
|
1005
|
+
logger,
|
|
1006
|
+
defaultBranch,
|
|
1007
|
+
requireCodeOwnerReviews,
|
|
1008
|
+
requiredStatusCheckContexts
|
|
1009
|
+
});
|
|
1010
|
+
} catch (e) {
|
|
1011
|
+
errors.assertError(e);
|
|
1012
|
+
logger.warn(`Skipping: default branch protection on '${repo}', ${e.message}`);
|
|
1013
|
+
}
|
|
851
1014
|
}
|
|
852
|
-
|
|
853
|
-
|
|
1015
|
+
}
|
|
1016
|
+
function extractCollaboratorName(collaborator) {
|
|
1017
|
+
if ("username" in collaborator)
|
|
1018
|
+
return collaborator.username;
|
|
1019
|
+
if ("user" in collaborator)
|
|
1020
|
+
return collaborator.user;
|
|
1021
|
+
return collaborator.team;
|
|
1022
|
+
}
|
|
854
1023
|
|
|
855
|
-
function
|
|
856
|
-
const { integrations,
|
|
1024
|
+
function createGithubActionsDispatchAction(options) {
|
|
1025
|
+
const { integrations, githubCredentialsProvider } = options;
|
|
857
1026
|
return createTemplateAction({
|
|
858
|
-
id: "
|
|
859
|
-
description: "
|
|
1027
|
+
id: "github:actions:dispatch",
|
|
1028
|
+
description: "Dispatches a GitHub Action workflow for a given branch or tag",
|
|
860
1029
|
schema: {
|
|
861
1030
|
input: {
|
|
862
1031
|
type: "object",
|
|
863
|
-
required: ["repoUrl"],
|
|
1032
|
+
required: ["repoUrl", "workflowId", "branchOrTagName"],
|
|
864
1033
|
properties: {
|
|
865
1034
|
repoUrl: {
|
|
866
1035
|
title: "Repository Location",
|
|
1036
|
+
description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the new repository name and 'owner' is an organization or username`,
|
|
867
1037
|
type: "string"
|
|
868
1038
|
},
|
|
869
|
-
|
|
870
|
-
title: "
|
|
1039
|
+
workflowId: {
|
|
1040
|
+
title: "Workflow ID",
|
|
1041
|
+
description: "The GitHub Action Workflow filename",
|
|
871
1042
|
type: "string"
|
|
872
1043
|
},
|
|
873
|
-
|
|
874
|
-
title: "
|
|
875
|
-
|
|
876
|
-
description: `Sets the default branch on the repository. The default value is 'master'`
|
|
877
|
-
},
|
|
878
|
-
gitCommitMessage: {
|
|
879
|
-
title: "Git Commit Message",
|
|
880
|
-
type: "string",
|
|
881
|
-
description: `Sets the commit message on the repository. The default value is 'initial commit'`
|
|
882
|
-
},
|
|
883
|
-
gitAuthorName: {
|
|
884
|
-
title: "Default Author Name",
|
|
885
|
-
type: "string",
|
|
886
|
-
description: `Sets the default author name for the commit. The default value is 'Scaffolder'`
|
|
887
|
-
},
|
|
888
|
-
gitAuthorEmail: {
|
|
889
|
-
title: "Default Author Email",
|
|
890
|
-
type: "string",
|
|
891
|
-
description: `Sets the default author email for the commit.`
|
|
892
|
-
},
|
|
893
|
-
sourcePath: {
|
|
894
|
-
title: "Source Path",
|
|
895
|
-
description: "Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.",
|
|
1044
|
+
branchOrTagName: {
|
|
1045
|
+
title: "Branch or Tag name",
|
|
1046
|
+
description: "The git branch or tag name used to dispatch the workflow",
|
|
896
1047
|
type: "string"
|
|
897
1048
|
},
|
|
1049
|
+
workflowInputs: {
|
|
1050
|
+
title: "Workflow Inputs",
|
|
1051
|
+
description: "Inputs keys and values to send to GitHub Action configured on the workflow file. The maximum number of properties is 10. ",
|
|
1052
|
+
type: "object"
|
|
1053
|
+
},
|
|
898
1054
|
token: {
|
|
899
1055
|
title: "Authentication Token",
|
|
900
1056
|
type: "string",
|
|
901
|
-
description: "The
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
},
|
|
905
|
-
output: {
|
|
906
|
-
type: "object",
|
|
907
|
-
properties: {
|
|
908
|
-
remoteUrl: {
|
|
909
|
-
title: "A URL to the repository with the provider",
|
|
910
|
-
type: "string"
|
|
911
|
-
},
|
|
912
|
-
repoContentsUrl: {
|
|
913
|
-
title: "A URL to the root of the repository",
|
|
914
|
-
type: "string"
|
|
1057
|
+
description: "The GITHUB_TOKEN to use for authorization to GitHub"
|
|
915
1058
|
}
|
|
916
1059
|
}
|
|
917
1060
|
}
|
|
918
1061
|
},
|
|
919
1062
|
async handler(ctx) {
|
|
920
|
-
var _a;
|
|
921
1063
|
const {
|
|
922
1064
|
repoUrl,
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
1065
|
+
workflowId,
|
|
1066
|
+
branchOrTagName,
|
|
1067
|
+
workflowInputs,
|
|
1068
|
+
token: providedToken
|
|
927
1069
|
} = ctx.input;
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
const integrationConfig = integrations.azure.byHost(host);
|
|
933
|
-
if (!integrationConfig) {
|
|
934
|
-
throw new errors.InputError(`No matching integration configuration for host ${host}, please check your integrations config`);
|
|
1070
|
+
ctx.logger.info(`Dispatching workflow ${workflowId} for repo ${repoUrl} on ${branchOrTagName}`);
|
|
1071
|
+
const { owner, repo } = parseRepoUrl(repoUrl, integrations);
|
|
1072
|
+
if (!owner) {
|
|
1073
|
+
throw new errors.InputError("Invalid repository owner provided in repoUrl");
|
|
935
1074
|
}
|
|
936
|
-
|
|
937
|
-
|
|
1075
|
+
const client = new octokit.Octokit(await getOctokitOptions({
|
|
1076
|
+
integrations,
|
|
1077
|
+
repoUrl,
|
|
1078
|
+
credentialsProvider: githubCredentialsProvider,
|
|
1079
|
+
token: providedToken
|
|
1080
|
+
}));
|
|
1081
|
+
await client.rest.actions.createWorkflowDispatch({
|
|
1082
|
+
owner,
|
|
1083
|
+
repo,
|
|
1084
|
+
workflow_id: workflowId,
|
|
1085
|
+
ref: branchOrTagName,
|
|
1086
|
+
inputs: workflowInputs
|
|
1087
|
+
});
|
|
1088
|
+
ctx.logger.info(`Workflow ${workflowId} dispatched successfully`);
|
|
1089
|
+
}
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
function createGithubIssuesLabelAction(options) {
|
|
1094
|
+
const { integrations, githubCredentialsProvider } = options;
|
|
1095
|
+
return createTemplateAction({
|
|
1096
|
+
id: "github:issues:label",
|
|
1097
|
+
description: "Adds labels to a pull request or issue on GitHub.",
|
|
1098
|
+
schema: {
|
|
1099
|
+
input: {
|
|
1100
|
+
type: "object",
|
|
1101
|
+
required: ["repoUrl", "number", "labels"],
|
|
1102
|
+
properties: {
|
|
1103
|
+
repoUrl: {
|
|
1104
|
+
title: "Repository Location",
|
|
1105
|
+
description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the repository name and 'owner' is an organization or username`,
|
|
1106
|
+
type: "string"
|
|
1107
|
+
},
|
|
1108
|
+
number: {
|
|
1109
|
+
title: "Pull Request or issue number",
|
|
1110
|
+
description: "The pull request or issue number to add labels to",
|
|
1111
|
+
type: "number"
|
|
1112
|
+
},
|
|
1113
|
+
labels: {
|
|
1114
|
+
title: "Labels",
|
|
1115
|
+
description: "The labels to add to the pull request or issue",
|
|
1116
|
+
type: "array",
|
|
1117
|
+
items: {
|
|
1118
|
+
type: "string"
|
|
1119
|
+
}
|
|
1120
|
+
},
|
|
1121
|
+
token: {
|
|
1122
|
+
title: "Authentication Token",
|
|
1123
|
+
type: "string",
|
|
1124
|
+
description: "The GITHUB_TOKEN to use for authorization to GitHub"
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
},
|
|
1129
|
+
async handler(ctx) {
|
|
1130
|
+
const { repoUrl, number, labels, token: providedToken } = ctx.input;
|
|
1131
|
+
const { owner, repo } = parseRepoUrl(repoUrl, integrations);
|
|
1132
|
+
ctx.logger.info(`Adding labels to ${number} issue on repo ${repo}`);
|
|
1133
|
+
if (!owner) {
|
|
1134
|
+
throw new errors.InputError("Invalid repository owner provided in repoUrl");
|
|
1135
|
+
}
|
|
1136
|
+
const client = new octokit.Octokit(await getOctokitOptions({
|
|
1137
|
+
integrations,
|
|
1138
|
+
credentialsProvider: githubCredentialsProvider,
|
|
1139
|
+
repoUrl,
|
|
1140
|
+
token: providedToken
|
|
1141
|
+
}));
|
|
1142
|
+
try {
|
|
1143
|
+
await client.rest.issues.addLabels({
|
|
1144
|
+
owner,
|
|
1145
|
+
repo,
|
|
1146
|
+
issue_number: number,
|
|
1147
|
+
labels
|
|
1148
|
+
});
|
|
1149
|
+
} catch (e) {
|
|
1150
|
+
errors.assertError(e);
|
|
1151
|
+
ctx.logger.warn(`Failed: adding labels to issue: '${number}' on repo: '${repo}', ${e.message}`);
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
});
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
const repoUrl = {
|
|
1158
|
+
title: "Repository Location",
|
|
1159
|
+
description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the new repository name and 'owner' is an organization or username`,
|
|
1160
|
+
type: "string"
|
|
1161
|
+
};
|
|
1162
|
+
const description = {
|
|
1163
|
+
title: "Repository Description",
|
|
1164
|
+
type: "string"
|
|
1165
|
+
};
|
|
1166
|
+
const access = {
|
|
1167
|
+
title: "Repository Access",
|
|
1168
|
+
description: `Sets an admin collaborator on the repository. Can either be a user reference different from 'owner' in 'repoUrl' or team reference, eg. 'org/team-name'`,
|
|
1169
|
+
type: "string"
|
|
1170
|
+
};
|
|
1171
|
+
const requireCodeOwnerReviews = {
|
|
1172
|
+
title: "Require CODEOWNER Reviews?",
|
|
1173
|
+
description: "Require an approved review in PR including files with a designated Code Owner",
|
|
1174
|
+
type: "boolean"
|
|
1175
|
+
};
|
|
1176
|
+
const requiredStatusCheckContexts = {
|
|
1177
|
+
title: "Required Status Check Contexts",
|
|
1178
|
+
description: "The list of status checks to require in order to merge into this branch",
|
|
1179
|
+
type: "array",
|
|
1180
|
+
items: {
|
|
1181
|
+
type: "string"
|
|
1182
|
+
}
|
|
1183
|
+
};
|
|
1184
|
+
const repoVisibility = {
|
|
1185
|
+
title: "Repository Visibility",
|
|
1186
|
+
type: "string",
|
|
1187
|
+
enum: ["private", "public", "internal"]
|
|
1188
|
+
};
|
|
1189
|
+
const deleteBranchOnMerge = {
|
|
1190
|
+
title: "Delete Branch On Merge",
|
|
1191
|
+
type: "boolean",
|
|
1192
|
+
description: `Delete the branch after merging the PR. The default value is 'false'`
|
|
1193
|
+
};
|
|
1194
|
+
const gitAuthorName = {
|
|
1195
|
+
title: "Default Author Name",
|
|
1196
|
+
type: "string",
|
|
1197
|
+
description: `Sets the default author name for the commit. The default value is 'Scaffolder'`
|
|
1198
|
+
};
|
|
1199
|
+
const gitAuthorEmail = {
|
|
1200
|
+
title: "Default Author Email",
|
|
1201
|
+
type: "string",
|
|
1202
|
+
description: `Sets the default author email for the commit.`
|
|
1203
|
+
};
|
|
1204
|
+
const allowMergeCommit = {
|
|
1205
|
+
title: "Allow Merge Commits",
|
|
1206
|
+
type: "boolean",
|
|
1207
|
+
description: `Allow merge commits. The default value is 'true'`
|
|
1208
|
+
};
|
|
1209
|
+
const allowSquashMerge = {
|
|
1210
|
+
title: "Allow Squash Merges",
|
|
1211
|
+
type: "boolean",
|
|
1212
|
+
description: `Allow squash merges. The default value is 'true'`
|
|
1213
|
+
};
|
|
1214
|
+
const allowRebaseMerge = {
|
|
1215
|
+
title: "Allow Rebase Merges",
|
|
1216
|
+
type: "boolean",
|
|
1217
|
+
description: `Allow rebase merges. The default value is 'true'`
|
|
1218
|
+
};
|
|
1219
|
+
const collaborators = {
|
|
1220
|
+
title: "Collaborators",
|
|
1221
|
+
description: "Provide additional users or teams with permissions",
|
|
1222
|
+
type: "array",
|
|
1223
|
+
items: {
|
|
1224
|
+
type: "object",
|
|
1225
|
+
additionalProperties: false,
|
|
1226
|
+
required: ["access"],
|
|
1227
|
+
properties: {
|
|
1228
|
+
access: {
|
|
1229
|
+
type: "string",
|
|
1230
|
+
description: "The type of access for the user",
|
|
1231
|
+
enum: ["push", "pull", "admin", "maintain", "triage"]
|
|
1232
|
+
},
|
|
1233
|
+
user: {
|
|
1234
|
+
type: "string",
|
|
1235
|
+
description: "The name of the user that will be added as a collaborator"
|
|
1236
|
+
},
|
|
1237
|
+
team: {
|
|
1238
|
+
type: "string",
|
|
1239
|
+
description: "The name of the team that will be added as a collaborator"
|
|
1240
|
+
}
|
|
1241
|
+
},
|
|
1242
|
+
oneOf: [{ required: ["user"] }, { required: ["team"] }]
|
|
1243
|
+
}
|
|
1244
|
+
};
|
|
1245
|
+
const token = {
|
|
1246
|
+
title: "Authentication Token",
|
|
1247
|
+
type: "string",
|
|
1248
|
+
description: "The token to use for authorization to GitHub"
|
|
1249
|
+
};
|
|
1250
|
+
const topics = {
|
|
1251
|
+
title: "Topics",
|
|
1252
|
+
type: "array",
|
|
1253
|
+
items: {
|
|
1254
|
+
type: "string"
|
|
1255
|
+
}
|
|
1256
|
+
};
|
|
1257
|
+
const defaultBranch = {
|
|
1258
|
+
title: "Default Branch",
|
|
1259
|
+
type: "string",
|
|
1260
|
+
description: `Sets the default branch on the repository. The default value is 'master'`
|
|
1261
|
+
};
|
|
1262
|
+
const protectDefaultBranch = {
|
|
1263
|
+
title: "Protect Default Branch",
|
|
1264
|
+
type: "boolean",
|
|
1265
|
+
description: `Protect the default branch after creating the repository. The default value is 'true'`
|
|
1266
|
+
};
|
|
1267
|
+
const gitCommitMessage = {
|
|
1268
|
+
title: "Git Commit Message",
|
|
1269
|
+
type: "string",
|
|
1270
|
+
description: `Sets the commit message on the repository. The default value is 'initial commit'`
|
|
1271
|
+
};
|
|
1272
|
+
const sourcePath = {
|
|
1273
|
+
title: "Source Path",
|
|
1274
|
+
description: "Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.",
|
|
1275
|
+
type: "string"
|
|
1276
|
+
};
|
|
1277
|
+
|
|
1278
|
+
const remoteUrl = {
|
|
1279
|
+
title: "A URL to the repository with the provider",
|
|
1280
|
+
type: "string"
|
|
1281
|
+
};
|
|
1282
|
+
const repoContentsUrl = {
|
|
1283
|
+
title: "A URL to the root of the repository",
|
|
1284
|
+
type: "string"
|
|
1285
|
+
};
|
|
1286
|
+
|
|
1287
|
+
function createGithubRepoCreateAction(options) {
|
|
1288
|
+
const { integrations, githubCredentialsProvider } = options;
|
|
1289
|
+
return createTemplateAction({
|
|
1290
|
+
id: "github:repo:create",
|
|
1291
|
+
description: "Creates a GitHub repository.",
|
|
1292
|
+
schema: {
|
|
1293
|
+
input: {
|
|
1294
|
+
type: "object",
|
|
1295
|
+
required: ["repoUrl"],
|
|
1296
|
+
properties: {
|
|
1297
|
+
repoUrl: repoUrl,
|
|
1298
|
+
description: description,
|
|
1299
|
+
access: access,
|
|
1300
|
+
requireCodeOwnerReviews: requireCodeOwnerReviews,
|
|
1301
|
+
requiredStatusCheckContexts: requiredStatusCheckContexts,
|
|
1302
|
+
repoVisibility: repoVisibility,
|
|
1303
|
+
deleteBranchOnMerge: deleteBranchOnMerge,
|
|
1304
|
+
allowMergeCommit: allowMergeCommit,
|
|
1305
|
+
allowSquashMerge: allowSquashMerge,
|
|
1306
|
+
allowRebaseMerge: allowRebaseMerge,
|
|
1307
|
+
collaborators: collaborators,
|
|
1308
|
+
token: token,
|
|
1309
|
+
topics: topics
|
|
1310
|
+
}
|
|
1311
|
+
},
|
|
1312
|
+
output: {
|
|
1313
|
+
type: "object",
|
|
1314
|
+
properties: {
|
|
1315
|
+
remoteUrl: remoteUrl,
|
|
1316
|
+
repoContentsUrl: repoContentsUrl
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
},
|
|
1320
|
+
async handler(ctx) {
|
|
1321
|
+
const {
|
|
1322
|
+
repoUrl,
|
|
1323
|
+
description,
|
|
1324
|
+
access,
|
|
1325
|
+
repoVisibility = "private",
|
|
1326
|
+
deleteBranchOnMerge = false,
|
|
1327
|
+
allowMergeCommit = true,
|
|
1328
|
+
allowSquashMerge = true,
|
|
1329
|
+
allowRebaseMerge = true,
|
|
1330
|
+
collaborators,
|
|
1331
|
+
topics,
|
|
1332
|
+
token: providedToken
|
|
1333
|
+
} = ctx.input;
|
|
1334
|
+
const octokitOptions = await getOctokitOptions({
|
|
1335
|
+
integrations,
|
|
1336
|
+
credentialsProvider: githubCredentialsProvider,
|
|
1337
|
+
token: providedToken,
|
|
1338
|
+
repoUrl
|
|
1339
|
+
});
|
|
1340
|
+
const client = new octokit.Octokit(octokitOptions);
|
|
1341
|
+
const { owner, repo } = parseRepoUrl(repoUrl, integrations);
|
|
1342
|
+
if (!owner) {
|
|
1343
|
+
throw new errors.InputError("Invalid repository owner provided in repoUrl");
|
|
1344
|
+
}
|
|
1345
|
+
const newRepo = await createGithubRepoWithCollaboratorsAndTopics(client, repo, owner, repoVisibility, description, deleteBranchOnMerge, allowMergeCommit, allowSquashMerge, allowRebaseMerge, access, collaborators, topics, ctx.logger);
|
|
1346
|
+
ctx.output("remoteUrl", newRepo.clone_url);
|
|
1347
|
+
}
|
|
1348
|
+
});
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
function createGithubRepoPushAction(options) {
|
|
1352
|
+
const { integrations, config, githubCredentialsProvider } = options;
|
|
1353
|
+
return createTemplateAction({
|
|
1354
|
+
id: "github:repo:push",
|
|
1355
|
+
description: "Initializes a git repository of contents in workspace and publishes it to GitHub.",
|
|
1356
|
+
schema: {
|
|
1357
|
+
input: {
|
|
1358
|
+
type: "object",
|
|
1359
|
+
required: ["repoUrl"],
|
|
1360
|
+
properties: {
|
|
1361
|
+
repoUrl: repoUrl,
|
|
1362
|
+
requireCodeOwnerReviews: requireCodeOwnerReviews,
|
|
1363
|
+
requiredStatusCheckContexts: requiredStatusCheckContexts,
|
|
1364
|
+
defaultBranch: defaultBranch,
|
|
1365
|
+
protectDefaultBranch: protectDefaultBranch,
|
|
1366
|
+
gitCommitMessage: gitCommitMessage,
|
|
1367
|
+
gitAuthorName: gitAuthorName,
|
|
1368
|
+
gitAuthorEmail: gitAuthorEmail,
|
|
1369
|
+
sourcePath: sourcePath,
|
|
1370
|
+
token: token
|
|
1371
|
+
}
|
|
1372
|
+
},
|
|
1373
|
+
output: {
|
|
1374
|
+
type: "object",
|
|
1375
|
+
properties: {
|
|
1376
|
+
remoteUrl: remoteUrl,
|
|
1377
|
+
repoContentsUrl: repoContentsUrl
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
},
|
|
1381
|
+
async handler(ctx) {
|
|
1382
|
+
const {
|
|
1383
|
+
repoUrl,
|
|
1384
|
+
defaultBranch = "master",
|
|
1385
|
+
protectDefaultBranch = true,
|
|
1386
|
+
gitCommitMessage = "initial commit",
|
|
1387
|
+
gitAuthorName,
|
|
1388
|
+
gitAuthorEmail,
|
|
1389
|
+
requireCodeOwnerReviews = false,
|
|
1390
|
+
requiredStatusCheckContexts = [],
|
|
1391
|
+
token: providedToken
|
|
1392
|
+
} = ctx.input;
|
|
1393
|
+
const { owner, repo } = parseRepoUrl(repoUrl, integrations);
|
|
1394
|
+
if (!owner) {
|
|
1395
|
+
throw new errors.InputError("Invalid repository owner provided in repoUrl");
|
|
1396
|
+
}
|
|
1397
|
+
const octokitOptions = await getOctokitOptions({
|
|
1398
|
+
integrations,
|
|
1399
|
+
credentialsProvider: githubCredentialsProvider,
|
|
1400
|
+
token: providedToken,
|
|
1401
|
+
repoUrl
|
|
1402
|
+
});
|
|
1403
|
+
const client = new octokit.Octokit(octokitOptions);
|
|
1404
|
+
const targetRepo = await client.rest.repos.get({ owner, repo });
|
|
1405
|
+
const remoteUrl = targetRepo.data.clone_url;
|
|
1406
|
+
const repoContentsUrl = `${targetRepo.data.html_url}/blob/${defaultBranch}`;
|
|
1407
|
+
await initRepoPushAndProtect(remoteUrl, octokitOptions.auth, ctx.workspacePath, ctx.input.sourcePath, defaultBranch, protectDefaultBranch, owner, client, repo, requireCodeOwnerReviews, requiredStatusCheckContexts, config, ctx.logger, gitCommitMessage, gitAuthorName, gitAuthorEmail);
|
|
1408
|
+
ctx.output("remoteUrl", remoteUrl);
|
|
1409
|
+
ctx.output("repoContentsUrl", repoContentsUrl);
|
|
1410
|
+
}
|
|
1411
|
+
});
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
function createGithubWebhookAction(options) {
|
|
1415
|
+
const { integrations, defaultWebhookSecret, githubCredentialsProvider } = options;
|
|
1416
|
+
const eventNames = webhooks.emitterEventNames.filter((event) => !event.includes("."));
|
|
1417
|
+
return createTemplateAction({
|
|
1418
|
+
id: "github:webhook",
|
|
1419
|
+
description: "Creates webhook for a repository on GitHub.",
|
|
1420
|
+
schema: {
|
|
1421
|
+
input: {
|
|
1422
|
+
type: "object",
|
|
1423
|
+
required: ["repoUrl", "webhookUrl"],
|
|
1424
|
+
properties: {
|
|
1425
|
+
repoUrl: {
|
|
1426
|
+
title: "Repository Location",
|
|
1427
|
+
description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the new repository name and 'owner' is an organization or username`,
|
|
1428
|
+
type: "string"
|
|
1429
|
+
},
|
|
1430
|
+
webhookUrl: {
|
|
1431
|
+
title: "Webhook URL",
|
|
1432
|
+
description: "The URL to which the payloads will be delivered",
|
|
1433
|
+
type: "string"
|
|
1434
|
+
},
|
|
1435
|
+
webhookSecret: {
|
|
1436
|
+
title: "Webhook Secret",
|
|
1437
|
+
description: "Webhook secret value. The default can be provided internally in action creation",
|
|
1438
|
+
type: "string"
|
|
1439
|
+
},
|
|
1440
|
+
events: {
|
|
1441
|
+
title: "Triggering Events",
|
|
1442
|
+
description: "Determines what events the hook is triggered for. Default: push",
|
|
1443
|
+
type: "array",
|
|
1444
|
+
oneOf: [
|
|
1445
|
+
{
|
|
1446
|
+
items: {
|
|
1447
|
+
type: "string",
|
|
1448
|
+
enum: eventNames
|
|
1449
|
+
}
|
|
1450
|
+
},
|
|
1451
|
+
{
|
|
1452
|
+
items: {
|
|
1453
|
+
type: "string",
|
|
1454
|
+
const: "*"
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
]
|
|
1458
|
+
},
|
|
1459
|
+
active: {
|
|
1460
|
+
title: "Active",
|
|
1461
|
+
type: "boolean",
|
|
1462
|
+
description: `Determines if notifications are sent when the webhook is triggered. Default: true`
|
|
1463
|
+
},
|
|
1464
|
+
contentType: {
|
|
1465
|
+
title: "Content Type",
|
|
1466
|
+
type: "string",
|
|
1467
|
+
enum: ["form", "json"],
|
|
1468
|
+
description: `The media type used to serialize the payloads. The default is 'form'`
|
|
1469
|
+
},
|
|
1470
|
+
insecureSsl: {
|
|
1471
|
+
title: "Insecure SSL",
|
|
1472
|
+
type: "boolean",
|
|
1473
|
+
description: `Determines whether the SSL certificate of the host for url will be verified when delivering payloads. Default 'false'`
|
|
1474
|
+
},
|
|
1475
|
+
token: {
|
|
1476
|
+
title: "Authentication Token",
|
|
1477
|
+
type: "string",
|
|
1478
|
+
description: "The GITHUB_TOKEN to use for authorization to GitHub"
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
},
|
|
1483
|
+
async handler(ctx) {
|
|
1484
|
+
const {
|
|
1485
|
+
repoUrl,
|
|
1486
|
+
webhookUrl,
|
|
1487
|
+
webhookSecret = defaultWebhookSecret,
|
|
1488
|
+
events = ["push"],
|
|
1489
|
+
active = true,
|
|
1490
|
+
contentType = "form",
|
|
1491
|
+
insecureSsl = false,
|
|
1492
|
+
token: providedToken
|
|
1493
|
+
} = ctx.input;
|
|
1494
|
+
ctx.logger.info(`Creating webhook ${webhookUrl} for repo ${repoUrl}`);
|
|
1495
|
+
const { owner, repo } = parseRepoUrl(repoUrl, integrations);
|
|
1496
|
+
if (!owner) {
|
|
1497
|
+
throw new errors.InputError("Invalid repository owner provided in repoUrl");
|
|
1498
|
+
}
|
|
1499
|
+
const client = new octokit.Octokit(await getOctokitOptions({
|
|
1500
|
+
integrations,
|
|
1501
|
+
credentialsProvider: githubCredentialsProvider,
|
|
1502
|
+
repoUrl,
|
|
1503
|
+
token: providedToken
|
|
1504
|
+
}));
|
|
1505
|
+
try {
|
|
1506
|
+
const insecure_ssl = insecureSsl ? "1" : "0";
|
|
1507
|
+
await client.rest.repos.createWebhook({
|
|
1508
|
+
owner,
|
|
1509
|
+
repo,
|
|
1510
|
+
config: {
|
|
1511
|
+
url: webhookUrl,
|
|
1512
|
+
content_type: contentType,
|
|
1513
|
+
secret: webhookSecret,
|
|
1514
|
+
insecure_ssl
|
|
1515
|
+
},
|
|
1516
|
+
events,
|
|
1517
|
+
active
|
|
1518
|
+
});
|
|
1519
|
+
ctx.logger.info(`Webhook '${webhookUrl}' created successfully`);
|
|
1520
|
+
} catch (e) {
|
|
1521
|
+
errors.assertError(e);
|
|
1522
|
+
ctx.logger.warn(`Failed: create webhook '${webhookUrl}' on repo: '${repo}', ${e.message}`);
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
});
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
function createPublishAzureAction(options) {
|
|
1529
|
+
const { integrations, config } = options;
|
|
1530
|
+
return createTemplateAction({
|
|
1531
|
+
id: "publish:azure",
|
|
1532
|
+
description: "Initializes a git repository of the content in the workspace, and publishes it to Azure.",
|
|
1533
|
+
schema: {
|
|
1534
|
+
input: {
|
|
1535
|
+
type: "object",
|
|
1536
|
+
required: ["repoUrl"],
|
|
1537
|
+
properties: {
|
|
1538
|
+
repoUrl: {
|
|
1539
|
+
title: "Repository Location",
|
|
1540
|
+
type: "string"
|
|
1541
|
+
},
|
|
1542
|
+
description: {
|
|
1543
|
+
title: "Repository Description",
|
|
1544
|
+
type: "string"
|
|
1545
|
+
},
|
|
1546
|
+
defaultBranch: {
|
|
1547
|
+
title: "Default Branch",
|
|
1548
|
+
type: "string",
|
|
1549
|
+
description: `Sets the default branch on the repository. The default value is 'master'`
|
|
1550
|
+
},
|
|
1551
|
+
gitCommitMessage: {
|
|
1552
|
+
title: "Git Commit Message",
|
|
1553
|
+
type: "string",
|
|
1554
|
+
description: `Sets the commit message on the repository. The default value is 'initial commit'`
|
|
1555
|
+
},
|
|
1556
|
+
gitAuthorName: {
|
|
1557
|
+
title: "Default Author Name",
|
|
1558
|
+
type: "string",
|
|
1559
|
+
description: `Sets the default author name for the commit. The default value is 'Scaffolder'`
|
|
1560
|
+
},
|
|
1561
|
+
gitAuthorEmail: {
|
|
1562
|
+
title: "Default Author Email",
|
|
1563
|
+
type: "string",
|
|
1564
|
+
description: `Sets the default author email for the commit.`
|
|
1565
|
+
},
|
|
1566
|
+
sourcePath: {
|
|
1567
|
+
title: "Source Path",
|
|
1568
|
+
description: "Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.",
|
|
1569
|
+
type: "string"
|
|
1570
|
+
},
|
|
1571
|
+
token: {
|
|
1572
|
+
title: "Authentication Token",
|
|
1573
|
+
type: "string",
|
|
1574
|
+
description: "The token to use for authorization to Azure"
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
},
|
|
1578
|
+
output: {
|
|
1579
|
+
type: "object",
|
|
1580
|
+
properties: {
|
|
1581
|
+
remoteUrl: {
|
|
1582
|
+
title: "A URL to the repository with the provider",
|
|
1583
|
+
type: "string"
|
|
1584
|
+
},
|
|
1585
|
+
repoContentsUrl: {
|
|
1586
|
+
title: "A URL to the root of the repository",
|
|
1587
|
+
type: "string"
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
},
|
|
1592
|
+
async handler(ctx) {
|
|
1593
|
+
var _a;
|
|
1594
|
+
const {
|
|
1595
|
+
repoUrl,
|
|
1596
|
+
defaultBranch = "master",
|
|
1597
|
+
gitCommitMessage = "initial commit",
|
|
1598
|
+
gitAuthorName,
|
|
1599
|
+
gitAuthorEmail
|
|
1600
|
+
} = ctx.input;
|
|
1601
|
+
const { owner, repo, host, organization } = parseRepoUrl(repoUrl, integrations);
|
|
1602
|
+
if (!organization) {
|
|
1603
|
+
throw new errors.InputError(`Invalid URL provider was included in the repo URL to create ${ctx.input.repoUrl}, missing organization`);
|
|
1604
|
+
}
|
|
1605
|
+
const integrationConfig = integrations.azure.byHost(host);
|
|
1606
|
+
if (!integrationConfig) {
|
|
1607
|
+
throw new errors.InputError(`No matching integration configuration for host ${host}, please check your integrations config`);
|
|
1608
|
+
}
|
|
1609
|
+
if (!integrationConfig.config.token && !ctx.input.token) {
|
|
1610
|
+
throw new errors.InputError(`No token provided for Azure Integration ${host}`);
|
|
938
1611
|
}
|
|
939
1612
|
const token = (_a = ctx.input.token) != null ? _a : integrationConfig.config.token;
|
|
940
1613
|
const authHandler = azureDevopsNodeApi.getPersonalAccessTokenHandler(token);
|
|
@@ -1731,43 +2404,6 @@ function createPublishGerritAction(options) {
|
|
|
1731
2404
|
});
|
|
1732
2405
|
}
|
|
1733
2406
|
|
|
1734
|
-
const DEFAULT_TIMEOUT_MS = 6e4;
|
|
1735
|
-
async function getOctokitOptions(options) {
|
|
1736
|
-
var _a;
|
|
1737
|
-
const { integrations, credentialsProvider, repoUrl, token } = options;
|
|
1738
|
-
const { owner, repo, host } = parseRepoUrl(repoUrl, integrations);
|
|
1739
|
-
const requestOptions = {
|
|
1740
|
-
timeout: DEFAULT_TIMEOUT_MS
|
|
1741
|
-
};
|
|
1742
|
-
if (!owner) {
|
|
1743
|
-
throw new errors.InputError(`No owner provided for repo ${repoUrl}`);
|
|
1744
|
-
}
|
|
1745
|
-
const integrationConfig = (_a = integrations.github.byHost(host)) == null ? void 0 : _a.config;
|
|
1746
|
-
if (!integrationConfig) {
|
|
1747
|
-
throw new errors.InputError(`No integration for host ${host}`);
|
|
1748
|
-
}
|
|
1749
|
-
if (token) {
|
|
1750
|
-
return {
|
|
1751
|
-
auth: token,
|
|
1752
|
-
baseUrl: integrationConfig.apiBaseUrl,
|
|
1753
|
-
previews: ["nebula-preview"],
|
|
1754
|
-
request: requestOptions
|
|
1755
|
-
};
|
|
1756
|
-
}
|
|
1757
|
-
const githubCredentialsProvider = credentialsProvider != null ? credentialsProvider : integration.DefaultGithubCredentialsProvider.fromIntegrations(integrations);
|
|
1758
|
-
const { token: credentialProviderToken } = await githubCredentialsProvider.getCredentials({
|
|
1759
|
-
url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`
|
|
1760
|
-
});
|
|
1761
|
-
if (!credentialProviderToken) {
|
|
1762
|
-
throw new errors.InputError(`No token available for host: ${host}, with owner ${owner}, and repo ${repo}`);
|
|
1763
|
-
}
|
|
1764
|
-
return {
|
|
1765
|
-
auth: credentialProviderToken,
|
|
1766
|
-
baseUrl: integrationConfig.apiBaseUrl,
|
|
1767
|
-
previews: ["nebula-preview"]
|
|
1768
|
-
};
|
|
1769
|
-
}
|
|
1770
|
-
|
|
1771
2407
|
function createPublishGithubAction(options) {
|
|
1772
2408
|
const { integrations, config, githubCredentialsProvider } = options;
|
|
1773
2409
|
return createTemplateAction({
|
|
@@ -1778,147 +2414,32 @@ function createPublishGithubAction(options) {
|
|
|
1778
2414
|
type: "object",
|
|
1779
2415
|
required: ["repoUrl"],
|
|
1780
2416
|
properties: {
|
|
1781
|
-
repoUrl:
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
requiredStatusCheckContexts: {
|
|
1801
|
-
title: "Required Status Check Contexts",
|
|
1802
|
-
description: "The list of status checks to require in order to merge into this branch",
|
|
1803
|
-
type: "array",
|
|
1804
|
-
items: {
|
|
1805
|
-
type: "string"
|
|
1806
|
-
}
|
|
1807
|
-
},
|
|
1808
|
-
repoVisibility: {
|
|
1809
|
-
title: "Repository Visibility",
|
|
1810
|
-
type: "string",
|
|
1811
|
-
enum: ["private", "public", "internal"]
|
|
1812
|
-
},
|
|
1813
|
-
defaultBranch: {
|
|
1814
|
-
title: "Default Branch",
|
|
1815
|
-
type: "string",
|
|
1816
|
-
description: `Sets the default branch on the repository. The default value is 'master'`
|
|
1817
|
-
},
|
|
1818
|
-
protectDefaultBranch: {
|
|
1819
|
-
title: "Protect Default Branch",
|
|
1820
|
-
type: "boolean",
|
|
1821
|
-
description: `Protect the default branch after creating the repository. The default value is 'true'`
|
|
1822
|
-
},
|
|
1823
|
-
deleteBranchOnMerge: {
|
|
1824
|
-
title: "Delete Branch On Merge",
|
|
1825
|
-
type: "boolean",
|
|
1826
|
-
description: `Delete the branch after merging the PR. The default value is 'false'`
|
|
1827
|
-
},
|
|
1828
|
-
gitCommitMessage: {
|
|
1829
|
-
title: "Git Commit Message",
|
|
1830
|
-
type: "string",
|
|
1831
|
-
description: `Sets the commit message on the repository. The default value is 'initial commit'`
|
|
1832
|
-
},
|
|
1833
|
-
gitAuthorName: {
|
|
1834
|
-
title: "Default Author Name",
|
|
1835
|
-
type: "string",
|
|
1836
|
-
description: `Sets the default author name for the commit. The default value is 'Scaffolder'`
|
|
1837
|
-
},
|
|
1838
|
-
gitAuthorEmail: {
|
|
1839
|
-
title: "Default Author Email",
|
|
1840
|
-
type: "string",
|
|
1841
|
-
description: `Sets the default author email for the commit.`
|
|
1842
|
-
},
|
|
1843
|
-
allowMergeCommit: {
|
|
1844
|
-
title: "Allow Merge Commits",
|
|
1845
|
-
type: "boolean",
|
|
1846
|
-
description: `Allow merge commits. The default value is 'true'`
|
|
1847
|
-
},
|
|
1848
|
-
allowSquashMerge: {
|
|
1849
|
-
title: "Allow Squash Merges",
|
|
1850
|
-
type: "boolean",
|
|
1851
|
-
description: `Allow squash merges. The default value is 'true'`
|
|
1852
|
-
},
|
|
1853
|
-
allowRebaseMerge: {
|
|
1854
|
-
title: "Allow Rebase Merges",
|
|
1855
|
-
type: "boolean",
|
|
1856
|
-
description: `Allow rebase merges. The default value is 'true'`
|
|
1857
|
-
},
|
|
1858
|
-
sourcePath: {
|
|
1859
|
-
title: "Source Path",
|
|
1860
|
-
description: "Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.",
|
|
1861
|
-
type: "string"
|
|
1862
|
-
},
|
|
1863
|
-
collaborators: {
|
|
1864
|
-
title: "Collaborators",
|
|
1865
|
-
description: "Provide additional users or teams with permissions",
|
|
1866
|
-
type: "array",
|
|
1867
|
-
items: {
|
|
1868
|
-
type: "object",
|
|
1869
|
-
additionalProperties: false,
|
|
1870
|
-
required: ["access"],
|
|
1871
|
-
properties: {
|
|
1872
|
-
access: {
|
|
1873
|
-
type: "string",
|
|
1874
|
-
description: "The type of access for the user",
|
|
1875
|
-
enum: ["push", "pull", "admin", "maintain", "triage"]
|
|
1876
|
-
},
|
|
1877
|
-
user: {
|
|
1878
|
-
type: "string",
|
|
1879
|
-
description: "The name of the user that will be added as a collaborator"
|
|
1880
|
-
},
|
|
1881
|
-
username: {
|
|
1882
|
-
type: "string",
|
|
1883
|
-
description: "Deprecated. Use the `team` or `user` field instead."
|
|
1884
|
-
},
|
|
1885
|
-
team: {
|
|
1886
|
-
type: "string",
|
|
1887
|
-
description: "The name of the team that will be added as a collaborator"
|
|
1888
|
-
}
|
|
1889
|
-
},
|
|
1890
|
-
oneOf: [
|
|
1891
|
-
{ required: ["user"] },
|
|
1892
|
-
{ required: ["username"] },
|
|
1893
|
-
{ required: ["team"] }
|
|
1894
|
-
]
|
|
1895
|
-
}
|
|
1896
|
-
},
|
|
1897
|
-
token: {
|
|
1898
|
-
title: "Authentication Token",
|
|
1899
|
-
type: "string",
|
|
1900
|
-
description: "The token to use for authorization to GitHub"
|
|
1901
|
-
},
|
|
1902
|
-
topics: {
|
|
1903
|
-
title: "Topics",
|
|
1904
|
-
type: "array",
|
|
1905
|
-
items: {
|
|
1906
|
-
type: "string"
|
|
1907
|
-
}
|
|
1908
|
-
}
|
|
2417
|
+
repoUrl: repoUrl,
|
|
2418
|
+
description: description,
|
|
2419
|
+
access: access,
|
|
2420
|
+
requireCodeOwnerReviews: requireCodeOwnerReviews,
|
|
2421
|
+
requiredStatusCheckContexts: requiredStatusCheckContexts,
|
|
2422
|
+
repoVisibility: repoVisibility,
|
|
2423
|
+
defaultBranch: defaultBranch,
|
|
2424
|
+
protectDefaultBranch: protectDefaultBranch,
|
|
2425
|
+
deleteBranchOnMerge: deleteBranchOnMerge,
|
|
2426
|
+
gitCommitMessage: gitCommitMessage,
|
|
2427
|
+
gitAuthorName: gitAuthorName,
|
|
2428
|
+
gitAuthorEmail: gitAuthorEmail,
|
|
2429
|
+
allowMergeCommit: allowMergeCommit,
|
|
2430
|
+
allowSquashMerge: allowSquashMerge,
|
|
2431
|
+
allowRebaseMerge: allowRebaseMerge,
|
|
2432
|
+
sourcePath: sourcePath,
|
|
2433
|
+
collaborators: collaborators,
|
|
2434
|
+
token: token,
|
|
2435
|
+
topics: topics
|
|
1909
2436
|
}
|
|
1910
2437
|
},
|
|
1911
2438
|
output: {
|
|
1912
2439
|
type: "object",
|
|
1913
2440
|
properties: {
|
|
1914
|
-
remoteUrl:
|
|
1915
|
-
|
|
1916
|
-
type: "string"
|
|
1917
|
-
},
|
|
1918
|
-
repoContentsUrl: {
|
|
1919
|
-
title: "A URL to the root of the repository",
|
|
1920
|
-
type: "string"
|
|
1921
|
-
}
|
|
2441
|
+
remoteUrl: remoteUrl,
|
|
2442
|
+
repoContentsUrl: repoContentsUrl
|
|
1922
2443
|
}
|
|
1923
2444
|
}
|
|
1924
2445
|
},
|
|
@@ -1943,10 +2464,6 @@ function createPublishGithubAction(options) {
|
|
|
1943
2464
|
topics,
|
|
1944
2465
|
token: providedToken
|
|
1945
2466
|
} = ctx.input;
|
|
1946
|
-
const { owner, repo } = parseRepoUrl(repoUrl, integrations);
|
|
1947
|
-
if (!owner) {
|
|
1948
|
-
throw new errors.InputError("Invalid repository owner provided in repoUrl");
|
|
1949
|
-
}
|
|
1950
2467
|
const octokitOptions = await getOctokitOptions({
|
|
1951
2468
|
integrations,
|
|
1952
2469
|
credentialsProvider: githubCredentialsProvider,
|
|
@@ -1954,148 +2471,19 @@ function createPublishGithubAction(options) {
|
|
|
1954
2471
|
repoUrl
|
|
1955
2472
|
});
|
|
1956
2473
|
const client = new octokit.Octokit(octokitOptions);
|
|
1957
|
-
const
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
const repoCreationPromise = user.data.type === "Organization" ? client.rest.repos.createInOrg({
|
|
1961
|
-
name: repo,
|
|
1962
|
-
org: owner,
|
|
1963
|
-
private: repoVisibility === "private",
|
|
1964
|
-
visibility: repoVisibility,
|
|
1965
|
-
description,
|
|
1966
|
-
delete_branch_on_merge: deleteBranchOnMerge,
|
|
1967
|
-
allow_merge_commit: allowMergeCommit,
|
|
1968
|
-
allow_squash_merge: allowSquashMerge,
|
|
1969
|
-
allow_rebase_merge: allowRebaseMerge
|
|
1970
|
-
}) : client.rest.repos.createForAuthenticatedUser({
|
|
1971
|
-
name: repo,
|
|
1972
|
-
private: repoVisibility === "private",
|
|
1973
|
-
description,
|
|
1974
|
-
delete_branch_on_merge: deleteBranchOnMerge,
|
|
1975
|
-
allow_merge_commit: allowMergeCommit,
|
|
1976
|
-
allow_squash_merge: allowSquashMerge,
|
|
1977
|
-
allow_rebase_merge: allowRebaseMerge
|
|
1978
|
-
});
|
|
1979
|
-
let newRepo;
|
|
1980
|
-
try {
|
|
1981
|
-
newRepo = (await repoCreationPromise).data;
|
|
1982
|
-
} catch (e) {
|
|
1983
|
-
errors.assertError(e);
|
|
1984
|
-
if (e.message === "Resource not accessible by integration") {
|
|
1985
|
-
ctx.logger.warn(`The GitHub app or token provided may not have the required permissions to create the ${user.data.type} repository ${owner}/${repo}.`);
|
|
1986
|
-
}
|
|
1987
|
-
throw new Error(`Failed to create the ${user.data.type} repository ${owner}/${repo}, ${e.message}`);
|
|
1988
|
-
}
|
|
1989
|
-
if (access == null ? void 0 : access.startsWith(`${owner}/`)) {
|
|
1990
|
-
const [, team] = access.split("/");
|
|
1991
|
-
await client.rest.teams.addOrUpdateRepoPermissionsInOrg({
|
|
1992
|
-
org: owner,
|
|
1993
|
-
team_slug: team,
|
|
1994
|
-
owner,
|
|
1995
|
-
repo,
|
|
1996
|
-
permission: "admin"
|
|
1997
|
-
});
|
|
1998
|
-
} else if (access && access !== owner) {
|
|
1999
|
-
await client.rest.repos.addCollaborator({
|
|
2000
|
-
owner,
|
|
2001
|
-
repo,
|
|
2002
|
-
username: access,
|
|
2003
|
-
permission: "admin"
|
|
2004
|
-
});
|
|
2005
|
-
}
|
|
2006
|
-
if (collaborators) {
|
|
2007
|
-
for (const collaborator of collaborators) {
|
|
2008
|
-
try {
|
|
2009
|
-
if ("user" in collaborator) {
|
|
2010
|
-
await client.rest.repos.addCollaborator({
|
|
2011
|
-
owner,
|
|
2012
|
-
repo,
|
|
2013
|
-
username: collaborator.user,
|
|
2014
|
-
permission: collaborator.access
|
|
2015
|
-
});
|
|
2016
|
-
} else if ("username" in collaborator) {
|
|
2017
|
-
ctx.logger.warn("The field `username` is deprecated in favor of `team` and will be removed in the future.");
|
|
2018
|
-
await client.rest.teams.addOrUpdateRepoPermissionsInOrg({
|
|
2019
|
-
org: owner,
|
|
2020
|
-
team_slug: collaborator.username,
|
|
2021
|
-
owner,
|
|
2022
|
-
repo,
|
|
2023
|
-
permission: collaborator.access
|
|
2024
|
-
});
|
|
2025
|
-
} else if ("team" in collaborator) {
|
|
2026
|
-
await client.rest.teams.addOrUpdateRepoPermissionsInOrg({
|
|
2027
|
-
org: owner,
|
|
2028
|
-
team_slug: collaborator.team,
|
|
2029
|
-
owner,
|
|
2030
|
-
repo,
|
|
2031
|
-
permission: collaborator.access
|
|
2032
|
-
});
|
|
2033
|
-
}
|
|
2034
|
-
} catch (e) {
|
|
2035
|
-
errors.assertError(e);
|
|
2036
|
-
const name = extractCollaboratorName(collaborator);
|
|
2037
|
-
ctx.logger.warn(`Skipping ${collaborator.access} access for ${name}, ${e.message}`);
|
|
2038
|
-
}
|
|
2039
|
-
}
|
|
2040
|
-
}
|
|
2041
|
-
if (topics) {
|
|
2042
|
-
try {
|
|
2043
|
-
await client.rest.repos.replaceAllTopics({
|
|
2044
|
-
owner,
|
|
2045
|
-
repo,
|
|
2046
|
-
names: topics.map((t) => t.toLowerCase())
|
|
2047
|
-
});
|
|
2048
|
-
} catch (e) {
|
|
2049
|
-
errors.assertError(e);
|
|
2050
|
-
ctx.logger.warn(`Skipping topics ${topics.join(" ")}, ${e.message}`);
|
|
2051
|
-
}
|
|
2474
|
+
const { owner, repo } = parseRepoUrl(repoUrl, integrations);
|
|
2475
|
+
if (!owner) {
|
|
2476
|
+
throw new errors.InputError("Invalid repository owner provided in repoUrl");
|
|
2052
2477
|
}
|
|
2478
|
+
const newRepo = await createGithubRepoWithCollaboratorsAndTopics(client, repo, owner, repoVisibility, description, deleteBranchOnMerge, allowMergeCommit, allowSquashMerge, allowRebaseMerge, access, collaborators, topics, ctx.logger);
|
|
2053
2479
|
const remoteUrl = newRepo.clone_url;
|
|
2054
2480
|
const repoContentsUrl = `${newRepo.html_url}/blob/${defaultBranch}`;
|
|
2055
|
-
|
|
2056
|
-
name: gitAuthorName ? gitAuthorName : config.getOptionalString("scaffolder.defaultAuthor.name"),
|
|
2057
|
-
email: gitAuthorEmail ? gitAuthorEmail : config.getOptionalString("scaffolder.defaultAuthor.email")
|
|
2058
|
-
};
|
|
2059
|
-
await initRepoAndPush({
|
|
2060
|
-
dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),
|
|
2061
|
-
remoteUrl,
|
|
2062
|
-
defaultBranch,
|
|
2063
|
-
auth: {
|
|
2064
|
-
username: "x-access-token",
|
|
2065
|
-
password: octokitOptions.auth
|
|
2066
|
-
},
|
|
2067
|
-
logger: ctx.logger,
|
|
2068
|
-
commitMessage: gitCommitMessage ? gitCommitMessage : config.getOptionalString("scaffolder.defaultCommitMessage"),
|
|
2069
|
-
gitAuthorInfo
|
|
2070
|
-
});
|
|
2071
|
-
if (protectDefaultBranch) {
|
|
2072
|
-
try {
|
|
2073
|
-
await enableBranchProtectionOnDefaultRepoBranch({
|
|
2074
|
-
owner,
|
|
2075
|
-
client,
|
|
2076
|
-
repoName: newRepo.name,
|
|
2077
|
-
logger: ctx.logger,
|
|
2078
|
-
defaultBranch,
|
|
2079
|
-
requireCodeOwnerReviews,
|
|
2080
|
-
requiredStatusCheckContexts
|
|
2081
|
-
});
|
|
2082
|
-
} catch (e) {
|
|
2083
|
-
errors.assertError(e);
|
|
2084
|
-
ctx.logger.warn(`Skipping: default branch protection on '${newRepo.name}', ${e.message}`);
|
|
2085
|
-
}
|
|
2086
|
-
}
|
|
2481
|
+
await initRepoPushAndProtect(remoteUrl, octokitOptions.auth, ctx.workspacePath, ctx.input.sourcePath, defaultBranch, protectDefaultBranch, owner, client, repo, requireCodeOwnerReviews, requiredStatusCheckContexts, config, ctx.logger, gitCommitMessage, gitAuthorName, gitAuthorEmail);
|
|
2087
2482
|
ctx.output("remoteUrl", remoteUrl);
|
|
2088
2483
|
ctx.output("repoContentsUrl", repoContentsUrl);
|
|
2089
2484
|
}
|
|
2090
2485
|
});
|
|
2091
2486
|
}
|
|
2092
|
-
function extractCollaboratorName(collaborator) {
|
|
2093
|
-
if ("username" in collaborator)
|
|
2094
|
-
return collaborator.username;
|
|
2095
|
-
if ("user" in collaborator)
|
|
2096
|
-
return collaborator.user;
|
|
2097
|
-
return collaborator.team;
|
|
2098
|
-
}
|
|
2099
2487
|
|
|
2100
2488
|
const DEFAULT_GLOB_PATTERNS = ["./**", "!.git"];
|
|
2101
2489
|
const isExecutable = (fileMode) => {
|
|
@@ -2453,6 +2841,11 @@ const createPublishGitlabMergeRequestAction = (options) => {
|
|
|
2453
2841
|
title: "Authentication Token",
|
|
2454
2842
|
type: "string",
|
|
2455
2843
|
description: "The token to use for authorization to GitLab"
|
|
2844
|
+
},
|
|
2845
|
+
removeSourceBranch: {
|
|
2846
|
+
title: "Delete source branch",
|
|
2847
|
+
type: "boolean",
|
|
2848
|
+
description: "Option to delete source branch once the MR has been merged. Default: false"
|
|
2456
2849
|
}
|
|
2457
2850
|
}
|
|
2458
2851
|
},
|
|
@@ -2523,7 +2916,10 @@ const createPublishGitlabMergeRequestAction = (options) => {
|
|
|
2523
2916
|
throw new errors.InputError(`Committing the changes to ${destinationBranch} failed ${e}`);
|
|
2524
2917
|
}
|
|
2525
2918
|
try {
|
|
2526
|
-
const mergeRequestUrl = await api.MergeRequests.create(projectPath, destinationBranch, String(defaultBranch), ctx.input.title, {
|
|
2919
|
+
const mergeRequestUrl = await api.MergeRequests.create(projectPath, destinationBranch, String(defaultBranch), ctx.input.title, {
|
|
2920
|
+
description: ctx.input.description,
|
|
2921
|
+
removeSourceBranch: ctx.input.removeSourceBranch ? ctx.input.removeSourceBranch : false
|
|
2922
|
+
}).then((mergeRequest) => {
|
|
2527
2923
|
return mergeRequest.web_url;
|
|
2528
2924
|
});
|
|
2529
2925
|
ctx.output("projectid", projectPath);
|
|
@@ -2536,253 +2932,6 @@ const createPublishGitlabMergeRequestAction = (options) => {
|
|
|
2536
2932
|
});
|
|
2537
2933
|
};
|
|
2538
2934
|
|
|
2539
|
-
function createGithubActionsDispatchAction(options) {
|
|
2540
|
-
const { integrations, githubCredentialsProvider } = options;
|
|
2541
|
-
return createTemplateAction({
|
|
2542
|
-
id: "github:actions:dispatch",
|
|
2543
|
-
description: "Dispatches a GitHub Action workflow for a given branch or tag",
|
|
2544
|
-
schema: {
|
|
2545
|
-
input: {
|
|
2546
|
-
type: "object",
|
|
2547
|
-
required: ["repoUrl", "workflowId", "branchOrTagName"],
|
|
2548
|
-
properties: {
|
|
2549
|
-
repoUrl: {
|
|
2550
|
-
title: "Repository Location",
|
|
2551
|
-
description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the new repository name and 'owner' is an organization or username`,
|
|
2552
|
-
type: "string"
|
|
2553
|
-
},
|
|
2554
|
-
workflowId: {
|
|
2555
|
-
title: "Workflow ID",
|
|
2556
|
-
description: "The GitHub Action Workflow filename",
|
|
2557
|
-
type: "string"
|
|
2558
|
-
},
|
|
2559
|
-
branchOrTagName: {
|
|
2560
|
-
title: "Branch or Tag name",
|
|
2561
|
-
description: "The git branch or tag name used to dispatch the workflow",
|
|
2562
|
-
type: "string"
|
|
2563
|
-
},
|
|
2564
|
-
workflowInputs: {
|
|
2565
|
-
title: "Workflow Inputs",
|
|
2566
|
-
description: "Inputs keys and values to send to GitHub Action configured on the workflow file. The maximum number of properties is 10. ",
|
|
2567
|
-
type: "object"
|
|
2568
|
-
},
|
|
2569
|
-
token: {
|
|
2570
|
-
title: "Authentication Token",
|
|
2571
|
-
type: "string",
|
|
2572
|
-
description: "The GITHUB_TOKEN to use for authorization to GitHub"
|
|
2573
|
-
}
|
|
2574
|
-
}
|
|
2575
|
-
}
|
|
2576
|
-
},
|
|
2577
|
-
async handler(ctx) {
|
|
2578
|
-
const {
|
|
2579
|
-
repoUrl,
|
|
2580
|
-
workflowId,
|
|
2581
|
-
branchOrTagName,
|
|
2582
|
-
workflowInputs,
|
|
2583
|
-
token: providedToken
|
|
2584
|
-
} = ctx.input;
|
|
2585
|
-
ctx.logger.info(`Dispatching workflow ${workflowId} for repo ${repoUrl} on ${branchOrTagName}`);
|
|
2586
|
-
const { owner, repo } = parseRepoUrl(repoUrl, integrations);
|
|
2587
|
-
if (!owner) {
|
|
2588
|
-
throw new errors.InputError("Invalid repository owner provided in repoUrl");
|
|
2589
|
-
}
|
|
2590
|
-
const client = new octokit.Octokit(await getOctokitOptions({
|
|
2591
|
-
integrations,
|
|
2592
|
-
repoUrl,
|
|
2593
|
-
credentialsProvider: githubCredentialsProvider,
|
|
2594
|
-
token: providedToken
|
|
2595
|
-
}));
|
|
2596
|
-
await client.rest.actions.createWorkflowDispatch({
|
|
2597
|
-
owner,
|
|
2598
|
-
repo,
|
|
2599
|
-
workflow_id: workflowId,
|
|
2600
|
-
ref: branchOrTagName,
|
|
2601
|
-
inputs: workflowInputs
|
|
2602
|
-
});
|
|
2603
|
-
ctx.logger.info(`Workflow ${workflowId} dispatched successfully`);
|
|
2604
|
-
}
|
|
2605
|
-
});
|
|
2606
|
-
}
|
|
2607
|
-
|
|
2608
|
-
function createGithubWebhookAction(options) {
|
|
2609
|
-
const { integrations, defaultWebhookSecret, githubCredentialsProvider } = options;
|
|
2610
|
-
const eventNames = webhooks.emitterEventNames.filter((event) => !event.includes("."));
|
|
2611
|
-
return createTemplateAction({
|
|
2612
|
-
id: "github:webhook",
|
|
2613
|
-
description: "Creates webhook for a repository on GitHub.",
|
|
2614
|
-
schema: {
|
|
2615
|
-
input: {
|
|
2616
|
-
type: "object",
|
|
2617
|
-
required: ["repoUrl", "webhookUrl"],
|
|
2618
|
-
properties: {
|
|
2619
|
-
repoUrl: {
|
|
2620
|
-
title: "Repository Location",
|
|
2621
|
-
description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the new repository name and 'owner' is an organization or username`,
|
|
2622
|
-
type: "string"
|
|
2623
|
-
},
|
|
2624
|
-
webhookUrl: {
|
|
2625
|
-
title: "Webhook URL",
|
|
2626
|
-
description: "The URL to which the payloads will be delivered",
|
|
2627
|
-
type: "string"
|
|
2628
|
-
},
|
|
2629
|
-
webhookSecret: {
|
|
2630
|
-
title: "Webhook Secret",
|
|
2631
|
-
description: "Webhook secret value. The default can be provided internally in action creation",
|
|
2632
|
-
type: "string"
|
|
2633
|
-
},
|
|
2634
|
-
events: {
|
|
2635
|
-
title: "Triggering Events",
|
|
2636
|
-
description: "Determines what events the hook is triggered for. Default: push",
|
|
2637
|
-
type: "array",
|
|
2638
|
-
oneOf: [
|
|
2639
|
-
{
|
|
2640
|
-
items: {
|
|
2641
|
-
type: "string",
|
|
2642
|
-
enum: eventNames
|
|
2643
|
-
}
|
|
2644
|
-
},
|
|
2645
|
-
{
|
|
2646
|
-
items: {
|
|
2647
|
-
type: "string",
|
|
2648
|
-
const: "*"
|
|
2649
|
-
}
|
|
2650
|
-
}
|
|
2651
|
-
]
|
|
2652
|
-
},
|
|
2653
|
-
active: {
|
|
2654
|
-
title: "Active",
|
|
2655
|
-
type: "boolean",
|
|
2656
|
-
description: `Determines if notifications are sent when the webhook is triggered. Default: true`
|
|
2657
|
-
},
|
|
2658
|
-
contentType: {
|
|
2659
|
-
title: "Content Type",
|
|
2660
|
-
type: "string",
|
|
2661
|
-
enum: ["form", "json"],
|
|
2662
|
-
description: `The media type used to serialize the payloads. The default is 'form'`
|
|
2663
|
-
},
|
|
2664
|
-
insecureSsl: {
|
|
2665
|
-
title: "Insecure SSL",
|
|
2666
|
-
type: "boolean",
|
|
2667
|
-
description: `Determines whether the SSL certificate of the host for url will be verified when delivering payloads. Default 'false'`
|
|
2668
|
-
},
|
|
2669
|
-
token: {
|
|
2670
|
-
title: "Authentication Token",
|
|
2671
|
-
type: "string",
|
|
2672
|
-
description: "The GITHUB_TOKEN to use for authorization to GitHub"
|
|
2673
|
-
}
|
|
2674
|
-
}
|
|
2675
|
-
}
|
|
2676
|
-
},
|
|
2677
|
-
async handler(ctx) {
|
|
2678
|
-
const {
|
|
2679
|
-
repoUrl,
|
|
2680
|
-
webhookUrl,
|
|
2681
|
-
webhookSecret = defaultWebhookSecret,
|
|
2682
|
-
events = ["push"],
|
|
2683
|
-
active = true,
|
|
2684
|
-
contentType = "form",
|
|
2685
|
-
insecureSsl = false,
|
|
2686
|
-
token: providedToken
|
|
2687
|
-
} = ctx.input;
|
|
2688
|
-
ctx.logger.info(`Creating webhook ${webhookUrl} for repo ${repoUrl}`);
|
|
2689
|
-
const { owner, repo } = parseRepoUrl(repoUrl, integrations);
|
|
2690
|
-
if (!owner) {
|
|
2691
|
-
throw new errors.InputError("Invalid repository owner provided in repoUrl");
|
|
2692
|
-
}
|
|
2693
|
-
const client = new octokit.Octokit(await getOctokitOptions({
|
|
2694
|
-
integrations,
|
|
2695
|
-
credentialsProvider: githubCredentialsProvider,
|
|
2696
|
-
repoUrl,
|
|
2697
|
-
token: providedToken
|
|
2698
|
-
}));
|
|
2699
|
-
try {
|
|
2700
|
-
const insecure_ssl = insecureSsl ? "1" : "0";
|
|
2701
|
-
await client.rest.repos.createWebhook({
|
|
2702
|
-
owner,
|
|
2703
|
-
repo,
|
|
2704
|
-
config: {
|
|
2705
|
-
url: webhookUrl,
|
|
2706
|
-
content_type: contentType,
|
|
2707
|
-
secret: webhookSecret,
|
|
2708
|
-
insecure_ssl
|
|
2709
|
-
},
|
|
2710
|
-
events,
|
|
2711
|
-
active
|
|
2712
|
-
});
|
|
2713
|
-
ctx.logger.info(`Webhook '${webhookUrl}' created successfully`);
|
|
2714
|
-
} catch (e) {
|
|
2715
|
-
errors.assertError(e);
|
|
2716
|
-
ctx.logger.warn(`Failed: create webhook '${webhookUrl}' on repo: '${repo}', ${e.message}`);
|
|
2717
|
-
}
|
|
2718
|
-
}
|
|
2719
|
-
});
|
|
2720
|
-
}
|
|
2721
|
-
|
|
2722
|
-
function createGithubIssuesLabelAction(options) {
|
|
2723
|
-
const { integrations, githubCredentialsProvider } = options;
|
|
2724
|
-
return createTemplateAction({
|
|
2725
|
-
id: "github:issues:label",
|
|
2726
|
-
description: "Adds labels to a pull request or issue on GitHub.",
|
|
2727
|
-
schema: {
|
|
2728
|
-
input: {
|
|
2729
|
-
type: "object",
|
|
2730
|
-
required: ["repoUrl", "number", "labels"],
|
|
2731
|
-
properties: {
|
|
2732
|
-
repoUrl: {
|
|
2733
|
-
title: "Repository Location",
|
|
2734
|
-
description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the repository name and 'owner' is an organization or username`,
|
|
2735
|
-
type: "string"
|
|
2736
|
-
},
|
|
2737
|
-
number: {
|
|
2738
|
-
title: "Pull Request or issue number",
|
|
2739
|
-
description: "The pull request or issue number to add labels to",
|
|
2740
|
-
type: "number"
|
|
2741
|
-
},
|
|
2742
|
-
labels: {
|
|
2743
|
-
title: "Labels",
|
|
2744
|
-
description: "The labels to add to the pull request or issue",
|
|
2745
|
-
type: "array",
|
|
2746
|
-
items: {
|
|
2747
|
-
type: "string"
|
|
2748
|
-
}
|
|
2749
|
-
},
|
|
2750
|
-
token: {
|
|
2751
|
-
title: "Authentication Token",
|
|
2752
|
-
type: "string",
|
|
2753
|
-
description: "The GITHUB_TOKEN to use for authorization to GitHub"
|
|
2754
|
-
}
|
|
2755
|
-
}
|
|
2756
|
-
}
|
|
2757
|
-
},
|
|
2758
|
-
async handler(ctx) {
|
|
2759
|
-
const { repoUrl, number, labels, token: providedToken } = ctx.input;
|
|
2760
|
-
const { owner, repo } = parseRepoUrl(repoUrl, integrations);
|
|
2761
|
-
ctx.logger.info(`Adding labels to ${number} issue on repo ${repo}`);
|
|
2762
|
-
if (!owner) {
|
|
2763
|
-
throw new errors.InputError("Invalid repository owner provided in repoUrl");
|
|
2764
|
-
}
|
|
2765
|
-
const client = new octokit.Octokit(await getOctokitOptions({
|
|
2766
|
-
integrations,
|
|
2767
|
-
credentialsProvider: githubCredentialsProvider,
|
|
2768
|
-
repoUrl,
|
|
2769
|
-
token: providedToken
|
|
2770
|
-
}));
|
|
2771
|
-
try {
|
|
2772
|
-
await client.rest.issues.addLabels({
|
|
2773
|
-
owner,
|
|
2774
|
-
repo,
|
|
2775
|
-
issue_number: number,
|
|
2776
|
-
labels
|
|
2777
|
-
});
|
|
2778
|
-
} catch (e) {
|
|
2779
|
-
errors.assertError(e);
|
|
2780
|
-
ctx.logger.warn(`Failed: adding labels to issue: '${number}' on repo: '${repo}', ${e.message}`);
|
|
2781
|
-
}
|
|
2782
|
-
}
|
|
2783
|
-
});
|
|
2784
|
-
}
|
|
2785
|
-
|
|
2786
2935
|
const createBuiltinActions = (options) => {
|
|
2787
2936
|
const {
|
|
2788
2937
|
reader,
|
|
@@ -2854,6 +3003,15 @@ const createBuiltinActions = (options) => {
|
|
|
2854
3003
|
createGithubIssuesLabelAction({
|
|
2855
3004
|
integrations,
|
|
2856
3005
|
githubCredentialsProvider
|
|
3006
|
+
}),
|
|
3007
|
+
createGithubRepoCreateAction({
|
|
3008
|
+
integrations,
|
|
3009
|
+
githubCredentialsProvider
|
|
3010
|
+
}),
|
|
3011
|
+
createGithubRepoPushAction({
|
|
3012
|
+
integrations,
|
|
3013
|
+
config,
|
|
3014
|
+
githubCredentialsProvider
|
|
2857
3015
|
})
|
|
2858
3016
|
];
|
|
2859
3017
|
return actions;
|
|
@@ -3985,6 +4143,8 @@ exports.createFilesystemDeleteAction = createFilesystemDeleteAction;
|
|
|
3985
4143
|
exports.createFilesystemRenameAction = createFilesystemRenameAction;
|
|
3986
4144
|
exports.createGithubActionsDispatchAction = createGithubActionsDispatchAction;
|
|
3987
4145
|
exports.createGithubIssuesLabelAction = createGithubIssuesLabelAction;
|
|
4146
|
+
exports.createGithubRepoCreateAction = createGithubRepoCreateAction;
|
|
4147
|
+
exports.createGithubRepoPushAction = createGithubRepoPushAction;
|
|
3988
4148
|
exports.createGithubWebhookAction = createGithubWebhookAction;
|
|
3989
4149
|
exports.createPublishAzureAction = createPublishAzureAction;
|
|
3990
4150
|
exports.createPublishBitbucketAction = createPublishBitbucketAction;
|