mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-04 07:26:11 +00:00
Update github integrations ui for organization and environment
This commit is contained in:
@@ -358,20 +358,48 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
try {
|
const orgs = await server.services.integrationAuth.getGithubOrgs({
|
||||||
const orgs = await server.services.integrationAuth.getGithubOrgs({
|
actorId: req.permission.id,
|
||||||
actorId: req.permission.id,
|
actor: req.permission.type,
|
||||||
actor: req.permission.type,
|
actorOrgId: req.permission.orgId,
|
||||||
actorOrgId: req.permission.orgId,
|
id: req.params.integrationAuthId
|
||||||
id: req.params.integrationAuthId
|
});
|
||||||
});
|
if (!orgs) throw new Error("No organization found.");
|
||||||
if (!orgs) throw new Error("No organization found.");
|
|
||||||
|
|
||||||
return { orgs: orgs || [] };
|
return { orgs };
|
||||||
} catch (e) {
|
}
|
||||||
console.error(e);
|
});
|
||||||
return { orgs: [] };
|
|
||||||
|
server.route({
|
||||||
|
url: "/:integrationAuthId/github/envs",
|
||||||
|
method: "GET",
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
|
schema: {
|
||||||
|
params: z.object({
|
||||||
|
integrationAuthId: z.string().trim()
|
||||||
|
}),
|
||||||
|
querystring: z.object({
|
||||||
|
repoOwner: z.string().trim(),
|
||||||
|
repoName: z.string().trim()
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
envs: z.object({ name: z.string(), envId: z.string() }).array()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
handler: async (req) => {
|
||||||
|
const envs = await server.services.integrationAuth.getGithubEnvs({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
id: req.params.integrationAuthId,
|
||||||
|
repoName: req.query.repoName,
|
||||||
|
repoOwner: req.query.repoOwner
|
||||||
|
});
|
||||||
|
if (!envs) throw new Error("No organization found.");
|
||||||
|
|
||||||
|
return { envs };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import {
|
|||||||
TIntegrationAuthAppsDTO,
|
TIntegrationAuthAppsDTO,
|
||||||
TIntegrationAuthBitbucketWorkspaceDTO,
|
TIntegrationAuthBitbucketWorkspaceDTO,
|
||||||
TIntegrationAuthChecklyGroupsDTO,
|
TIntegrationAuthChecklyGroupsDTO,
|
||||||
|
TIntegrationAuthGithubEnvsDTO,
|
||||||
TIntegrationAuthGithubOrgsDTO,
|
TIntegrationAuthGithubOrgsDTO,
|
||||||
TIntegrationAuthNorthflankSecretGroupDTO,
|
TIntegrationAuthNorthflankSecretGroupDTO,
|
||||||
TIntegrationAuthQoveryEnvironmentsDTO,
|
TIntegrationAuthQoveryEnvironmentsDTO,
|
||||||
@@ -401,13 +402,51 @@ export const integrationAuthServiceFactory = ({
|
|||||||
auth: accessToken
|
auth: accessToken
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data } = await octokit.request("GET /organizations", {
|
const { data } = await octokit.request("GET /user/orgs", {
|
||||||
headers: {
|
headers: {
|
||||||
"X-GitHub-Api-Version": "2022-11-28"
|
"X-GitHub-Api-Version": "2022-11-28"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!data) return [];
|
if (!data) return [];
|
||||||
return data.map(({ login: name, id: orgId }) => ({ name, orgId }));
|
return data.map(({ login: name, id: orgId }) => ({ name, orgId: String(orgId) }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const getGithubEnvs = async ({
|
||||||
|
actorId,
|
||||||
|
actor,
|
||||||
|
actorOrgId,
|
||||||
|
id,
|
||||||
|
repoOwner,
|
||||||
|
repoName
|
||||||
|
}: TIntegrationAuthGithubEnvsDTO) => {
|
||||||
|
const integrationAuth = await integrationAuthDAL.findById(id);
|
||||||
|
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
|
||||||
|
|
||||||
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
integrationAuth.projectId,
|
||||||
|
actorOrgId
|
||||||
|
);
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
|
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
|
const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey);
|
||||||
|
|
||||||
|
const octokit = new Octokit({
|
||||||
|
auth: accessToken
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: { environments }
|
||||||
|
} = await octokit.request("GET /repos/{owner}/{repo}/environments", {
|
||||||
|
headers: {
|
||||||
|
"X-GitHub-Api-Version": "2022-11-28"
|
||||||
|
},
|
||||||
|
owner: repoOwner,
|
||||||
|
repo: repoName
|
||||||
|
});
|
||||||
|
if (!environments) return [];
|
||||||
|
return environments.map(({ id: envId, name }) => ({ name, envId: String(envId) }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const getQoveryOrgs = async ({ actorId, actor, actorOrgId, id }: TIntegrationAuthQoveryOrgsDTO) => {
|
const getQoveryOrgs = async ({ actorId, actor, actorOrgId, id }: TIntegrationAuthQoveryOrgsDTO) => {
|
||||||
@@ -762,9 +801,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
|
|
||||||
while (hasNextPage) {
|
while (hasNextPage) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
const { data }: { data: { values: TBitbucketWorkspace[]; next: string } } = await request.get(
|
const { data }: { data: { values: TBitbucketWorkspace[]; next: string } } = await request.get(workspaceUrl, {
|
||||||
workspaceUrl,
|
|
||||||
{
|
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${accessToken}`,
|
Authorization: `Bearer ${accessToken}`,
|
||||||
"Accept-Encoding": "application/json"
|
"Accept-Encoding": "application/json"
|
||||||
@@ -941,6 +978,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
getVercelBranches,
|
getVercelBranches,
|
||||||
getApps,
|
getApps,
|
||||||
getGithubOrgs,
|
getGithubOrgs,
|
||||||
|
getGithubEnvs,
|
||||||
getChecklyGroups,
|
getChecklyGroups,
|
||||||
getQoveryApps,
|
getQoveryApps,
|
||||||
getQoveryEnvs,
|
getQoveryEnvs,
|
||||||
|
|||||||
@@ -48,6 +48,12 @@ export type TIntegrationAuthGithubOrgsDTO = {
|
|||||||
id: string;
|
id: string;
|
||||||
} & Omit<TProjectPermission, "projectId">;
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
|
export type TIntegrationAuthGithubEnvsDTO = {
|
||||||
|
id: string;
|
||||||
|
repoName: string;
|
||||||
|
repoOwner: string;
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
export type TIntegrationAuthQoveryOrgsDTO = {
|
export type TIntegrationAuthQoveryOrgsDTO = {
|
||||||
id: string;
|
id: string;
|
||||||
} & Omit<TProjectPermission, "projectId">;
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export {
|
|||||||
useGetIntegrationAuthBitBucketWorkspaces,
|
useGetIntegrationAuthBitBucketWorkspaces,
|
||||||
useGetIntegrationAuthById,
|
useGetIntegrationAuthById,
|
||||||
useGetIntegrationAuthChecklyGroups,
|
useGetIntegrationAuthChecklyGroups,
|
||||||
|
useGetIntegrationAuthGithubEnvs,
|
||||||
useGetIntegrationAuthGithubOrgs,
|
useGetIntegrationAuthGithubOrgs,
|
||||||
useGetIntegrationAuthNorthflankSecretGroups,
|
useGetIntegrationAuthNorthflankSecretGroups,
|
||||||
useGetIntegrationAuthRailwayEnvironments,
|
useGetIntegrationAuthRailwayEnvironments,
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ const integrationAuthKeys = {
|
|||||||
}) => [{ integrationAuthId, accountId }, "integrationAuthChecklyGroups"] as const,
|
}) => [{ integrationAuthId, accountId }, "integrationAuthChecklyGroups"] as const,
|
||||||
getIntegrationAuthGithubOrgs: (integrationAuthId: string) =>
|
getIntegrationAuthGithubOrgs: (integrationAuthId: string) =>
|
||||||
[{ integrationAuthId }, "integrationAuthGithubOrgs"] as const,
|
[{ integrationAuthId }, "integrationAuthGithubOrgs"] as const,
|
||||||
|
getIntegrationAuthGithubEnvs: (integrationAuthId: string, repoName: string, repoOwner: string) =>
|
||||||
|
[{ integrationAuthId, repoName, repoOwner }, "integrationAuthGithubOrgs"] as const,
|
||||||
getIntegrationAuthQoveryOrgs: (integrationAuthId: string) =>
|
getIntegrationAuthQoveryOrgs: (integrationAuthId: string) =>
|
||||||
[{ integrationAuthId }, "integrationAuthQoveryOrgs"] as const,
|
[{ integrationAuthId }, "integrationAuthQoveryOrgs"] as const,
|
||||||
getIntegrationAuthQoveryProjects: ({
|
getIntegrationAuthQoveryProjects: ({
|
||||||
@@ -186,6 +188,22 @@ const fetchIntegrationAuthGithubOrgs = async (integrationAuthId: string) => {
|
|||||||
return orgs;
|
return orgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchIntegrationAuthGithubEnvs = async (
|
||||||
|
integrationAuthId: string,
|
||||||
|
repoName: string,
|
||||||
|
repoOwner: string
|
||||||
|
) => {
|
||||||
|
if (!repoName || !repoOwner) return [];
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: { envs }
|
||||||
|
} = await apiRequest.get<{ envs: Array<{ name: string; envId: string }> }>(
|
||||||
|
`/api/v1/integration-auth/${integrationAuthId}/github/envs?repoName=${repoName}&repoOwner=${repoOwner}`
|
||||||
|
);
|
||||||
|
|
||||||
|
return envs;
|
||||||
|
};
|
||||||
|
|
||||||
const fetchIntegrationAuthQoveryOrgs = async (integrationAuthId: string) => {
|
const fetchIntegrationAuthQoveryOrgs = async (integrationAuthId: string) => {
|
||||||
const {
|
const {
|
||||||
data: { orgs }
|
data: { orgs }
|
||||||
@@ -485,6 +503,22 @@ export const useGetIntegrationAuthGithubOrgs = (integrationAuthId: string) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useGetIntegrationAuthGithubEnvs = (
|
||||||
|
integrationAuthId: string,
|
||||||
|
repoName: string,
|
||||||
|
repoOwner: string
|
||||||
|
) => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: integrationAuthKeys.getIntegrationAuthGithubEnvs(
|
||||||
|
integrationAuthId,
|
||||||
|
repoName,
|
||||||
|
repoOwner
|
||||||
|
),
|
||||||
|
queryFn: () => fetchIntegrationAuthGithubEnvs(integrationAuthId, repoName, repoOwner),
|
||||||
|
enabled: true
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const useGetIntegrationAuthQoveryOrgs = (integrationAuthId: string) => {
|
export const useGetIntegrationAuthQoveryOrgs = (integrationAuthId: string) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: integrationAuthKeys.getIntegrationAuthQoveryOrgs(integrationAuthId),
|
queryKey: integrationAuthKeys.getIntegrationAuthQoveryOrgs(integrationAuthId),
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import {
|
|||||||
useCreateIntegration,
|
useCreateIntegration,
|
||||||
useGetIntegrationAuthApps,
|
useGetIntegrationAuthApps,
|
||||||
useGetIntegrationAuthById,
|
useGetIntegrationAuthById,
|
||||||
|
useGetIntegrationAuthGithubEnvs,
|
||||||
useGetIntegrationAuthGithubOrgs,
|
useGetIntegrationAuthGithubOrgs,
|
||||||
useGetWorkspaceById
|
useGetWorkspaceById
|
||||||
} from "@app/hooks/api";
|
} from "@app/hooks/api";
|
||||||
@@ -50,13 +51,8 @@ enum TabSections {
|
|||||||
Options = "options"
|
Options = "options"
|
||||||
}
|
}
|
||||||
|
|
||||||
const targetEnv = [
|
const targetEnv = ["github-repo", "github-org", "github-env"] as const;
|
||||||
"github-repo",
|
type TargetEnv = (typeof targetEnv)[number];
|
||||||
"github-org",
|
|
||||||
"github-env"
|
|
||||||
] as const;
|
|
||||||
type TargetEnv = typeof targetEnv[number];
|
|
||||||
|
|
||||||
|
|
||||||
const schema = yup.object({
|
const schema = yup.object({
|
||||||
selectedSourceEnvironment: yup.string().trim().required("Project Environment is required"),
|
selectedSourceEnvironment: yup.string().trim().required("Project Environment is required"),
|
||||||
@@ -64,22 +60,31 @@ const schema = yup.object({
|
|||||||
secretSuffix: yup.string().trim().optional(),
|
secretSuffix: yup.string().trim().optional(),
|
||||||
|
|
||||||
scope: yup.mixed<TargetEnv>().oneOf(targetEnv.slice()).required(),
|
scope: yup.mixed<TargetEnv>().oneOf(targetEnv.slice()).required(),
|
||||||
repoIds: yup
|
|
||||||
.array(yup.string().required())
|
repoIds: yup.mixed().when("scope", {
|
||||||
.min(1, "Select atleast one repo") // .min() not working showing error for empty array
|
is: "github-repo",
|
||||||
.optional(),
|
then: yup.array(yup.string().required()).min(1, "Select atleast one repositories")
|
||||||
repoId: yup
|
}),
|
||||||
.string()
|
|
||||||
.optional(),
|
repoName: yup.mixed().when("scope", {
|
||||||
|
is: "github-env",
|
||||||
envId: yup
|
then: yup.string().required("Repository is required")
|
||||||
.string()
|
}),
|
||||||
.optional(),
|
|
||||||
|
repoOwner: yup.mixed().when("scope", {
|
||||||
orgId: yup
|
is: "github-env",
|
||||||
.string()
|
then: yup.string().required("Repository is required")
|
||||||
.optional(),
|
}),
|
||||||
|
|
||||||
|
envId: yup.mixed().when("scope", {
|
||||||
|
is: "github-env",
|
||||||
|
then: yup.string().required("Environment is required")
|
||||||
|
}),
|
||||||
|
|
||||||
|
orgId: yup.mixed().when("scope", {
|
||||||
|
is: "github-org",
|
||||||
|
then: yup.string().required("Organization is required")
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
type FormData = yup.InferType<typeof schema>;
|
type FormData = yup.InferType<typeof schema>;
|
||||||
@@ -89,33 +94,41 @@ export default function GitHubCreateIntegrationPage() {
|
|||||||
const { mutateAsync } = useCreateIntegration();
|
const { mutateAsync } = useCreateIntegration();
|
||||||
const { createNotification } = useNotificationContext();
|
const { createNotification } = useNotificationContext();
|
||||||
|
|
||||||
const { integrationAuthId } = queryString.parse(router.asPath.split("?")[1]);
|
const integrationAuthId =
|
||||||
|
(queryString.parse(router.asPath.split("?")[1]).integrationAuthId as string) ?? "";
|
||||||
|
|
||||||
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
|
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
|
||||||
const { data: integrationAuth } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
|
const { data: integrationAuth } = useGetIntegrationAuthById(integrationAuthId);
|
||||||
|
|
||||||
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } =
|
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } =
|
||||||
useGetIntegrationAuthApps({
|
useGetIntegrationAuthApps({
|
||||||
integrationAuthId: (integrationAuthId as string) ?? ""
|
integrationAuthId
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: integrationAuthOrgs } =
|
const { data: integrationAuthOrgs } = useGetIntegrationAuthGithubOrgs(
|
||||||
useGetIntegrationAuthGithubOrgs(integrationAuthId as string);
|
integrationAuthId as string
|
||||||
|
);
|
||||||
|
|
||||||
const { control, handleSubmit, watch, setValue } = useForm<FormData>({
|
const { control, handleSubmit, watch, setValue } = useForm<FormData>({
|
||||||
resolver: yupResolver(schema),
|
resolver: yupResolver(schema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
selectedSourceEnvironment: "",
|
|
||||||
secretPath: "/",
|
secretPath: "/",
|
||||||
repoIds: [],
|
scope: "github-repo",
|
||||||
secretSuffix: "",
|
repoIds: []
|
||||||
scope: "github-repo"
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const scope = watch("scope");
|
const scope = watch("scope");
|
||||||
|
|
||||||
const repoIds = watch("repoIds");
|
const repoIds = watch("repoIds");
|
||||||
|
const repoName = watch("repoName");
|
||||||
|
const repoOwner = watch("repoOwner");
|
||||||
|
|
||||||
|
const { data: integrationAuthGithubEnvs } = useGetIntegrationAuthGithubEnvs(
|
||||||
|
integrationAuthId as string,
|
||||||
|
repoName,
|
||||||
|
repoOwner
|
||||||
|
);
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -124,61 +137,93 @@ export default function GitHubCreateIntegrationPage() {
|
|||||||
}
|
}
|
||||||
}, [workspace]);
|
}, [workspace]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (integrationAuthApps) {
|
|
||||||
if (integrationAuthApps.length > 0) {
|
|
||||||
setValue("repoIds", [String(integrationAuthApps[0].appId)]);
|
|
||||||
} else {
|
|
||||||
setValue("repoIds", ["none"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [integrationAuthApps]);
|
|
||||||
|
|
||||||
const onFormSubmit = async (data: FormData) => {
|
const onFormSubmit = async (data: FormData) => {
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
if (!integrationAuth?.id) return;
|
if (!integrationAuth?.id) return;
|
||||||
|
|
||||||
const targetApps = integrationAuthApps?.filter((integrationAuthApp) =>
|
switch (data.scope) {
|
||||||
data.repoIds?.includes(String(integrationAuthApp.appId))
|
case "github-repo": {
|
||||||
);
|
const targetApps = integrationAuthApps?.filter((integrationAuthApp) =>
|
||||||
|
data.repoIds?.includes(String(integrationAuthApp.appId))
|
||||||
|
);
|
||||||
|
|
||||||
if (!targetApps) return;
|
if (!targetApps) return;
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
targetApps.map(async (targetApp) => {
|
targetApps.map(async (targetApp) => {
|
||||||
|
await mutateAsync({
|
||||||
|
integrationAuthId: integrationAuth?.id,
|
||||||
|
isActive: true,
|
||||||
|
scope: data.scope,
|
||||||
|
secretPath: data.secretPath,
|
||||||
|
sourceEnvironment: data.selectedSourceEnvironment,
|
||||||
|
app: targetApp.name, // repo name
|
||||||
|
owner: targetApp.owner, // repo owner
|
||||||
|
metadata: {
|
||||||
|
secretSuffix: data.secretSuffix
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "github-org":
|
||||||
await mutateAsync({
|
await mutateAsync({
|
||||||
integrationAuthId: integrationAuth?.id,
|
integrationAuthId: integrationAuth?.id,
|
||||||
isActive: true,
|
isActive: true,
|
||||||
app: targetApp.name,
|
|
||||||
owner: targetApp.owner,
|
|
||||||
secretPath: data.secretPath,
|
secretPath: data.secretPath,
|
||||||
sourceEnvironment: data.selectedSourceEnvironment,
|
sourceEnvironment: data.selectedSourceEnvironment,
|
||||||
|
scope: data.scope,
|
||||||
|
targetServiceId: data.orgId, // github org id
|
||||||
metadata: {
|
metadata: {
|
||||||
secretSuffix: data.secretSuffix
|
secretSuffix: data.secretSuffix
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
break;
|
||||||
);
|
|
||||||
|
case "github-env":
|
||||||
|
await mutateAsync({
|
||||||
|
integrationAuthId: integrationAuth?.id,
|
||||||
|
isActive: true,
|
||||||
|
secretPath: data.secretPath,
|
||||||
|
sourceEnvironment: data.selectedSourceEnvironment,
|
||||||
|
scope: data.scope,
|
||||||
|
app: repoName, // repo name // TODO: CHANGE THIS STATE INTO YUP
|
||||||
|
owner: repoOwner, // repo owner
|
||||||
|
targetEnvironmentId: data.envId, // github environment id
|
||||||
|
metadata: {
|
||||||
|
secretSuffix: data.secretSuffix
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error("Invalid scope");
|
||||||
|
}
|
||||||
|
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
router.push(`/integrations/${localStorage.getItem("projectData.id")}`);
|
router.push(`/integrations/${localStorage.getItem("projectData.id")}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|
||||||
|
let errorMessage: string = "Something went wrong!";
|
||||||
if (axios.isAxiosError(err)) {
|
if (axios.isAxiosError(err)) {
|
||||||
const { message } = err?.response?.data as { message: string };
|
const { message } = err?.response?.data as { message: string };
|
||||||
createNotification({
|
errorMessage = message;
|
||||||
text: message,
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createNotification({
|
||||||
|
text: errorMessage,
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return integrationAuth && workspace && integrationAuthApps ? (
|
return integrationAuth && workspace && integrationAuthApps ? (
|
||||||
<div className="flex h-full w-full flex-col items-center justify-center">
|
<div className="flex w-full flex-col items-center justify-center py-4">
|
||||||
<Head>
|
<Head>
|
||||||
<title>Set Up GitHub Integration</title>
|
<title>Set Up GitHub Integration</title>
|
||||||
<link rel="icon" href="/infisical.ico" />
|
<link rel="icon" href="/infisical.ico" />
|
||||||
@@ -239,7 +284,7 @@ export default function GitHubCreateIntegrationPage() {
|
|||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
defaultValue={field.value}
|
defaultValue={field.value}
|
||||||
onValueChange={(e) => onChange(e)}
|
onValueChange={onChange}
|
||||||
className="w-full border border-mineshaft-500"
|
className="w-full border border-mineshaft-500"
|
||||||
>
|
>
|
||||||
{workspace?.environments.map((sourceEnvironment) => (
|
{workspace?.environments.map((sourceEnvironment) => (
|
||||||
@@ -267,19 +312,14 @@ export default function GitHubCreateIntegrationPage() {
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="scope"
|
name="scope"
|
||||||
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
||||||
<FormControl
|
<FormControl label="Scope" errorText={error?.message} isError={Boolean(error)}>
|
||||||
label="Scope"
|
|
||||||
errorText={error?.message}
|
|
||||||
isError={Boolean(error)}
|
|
||||||
>
|
|
||||||
<Select
|
<Select
|
||||||
defaultValue={field.value}
|
defaultValue={field.value}
|
||||||
onValueChange={(e) => onChange(e)}
|
onValueChange={onChange}
|
||||||
className="w-full border border-mineshaft-500"
|
className="w-full border border-mineshaft-500"
|
||||||
>
|
>
|
||||||
<SelectItem value="github-repo">Github Repositories</SelectItem>
|
<SelectItem value="github-repo">Github Repositories</SelectItem>
|
||||||
@@ -289,17 +329,15 @@ export default function GitHubCreateIntegrationPage() {
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
{scope === "github-repo" && (
|
||||||
{scope === "github-repo" && repoIds && (
|
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="repoIds"
|
name="repoIds"
|
||||||
render={({ field: { onChange }}) => (
|
render={({ field: { onChange }, fieldState: { error } }) => (
|
||||||
<FormControl
|
<FormControl
|
||||||
label="GitHub Repo"
|
label="Repositories"
|
||||||
// BUG: yup.min() not working as expected needs to be fixed
|
isError={Boolean(error?.message)}
|
||||||
errorText="Atleast one repo is required"
|
errorText={error?.message}
|
||||||
isError={repoIds?.length === 0}
|
|
||||||
>
|
>
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
@@ -335,7 +373,8 @@ export default function GitHubCreateIntegrationPage() {
|
|||||||
if (repoIds.includes(String(integrationAuthApp.appId))) {
|
if (repoIds.includes(String(integrationAuthApp.appId))) {
|
||||||
onChange(
|
onChange(
|
||||||
repoIds.filter(
|
repoIds.filter(
|
||||||
(appId) => appId !== String(integrationAuthApp.appId)
|
(appId: string) =>
|
||||||
|
appId !== String(integrationAuthApp.appId)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@@ -368,68 +407,73 @@ export default function GitHubCreateIntegrationPage() {
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
)}
|
)}
|
||||||
{scope === "github-org" && (
|
{scope === "github-org" && (
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="orgId"
|
name="orgId"
|
||||||
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
||||||
<FormControl
|
<FormControl
|
||||||
label="Organization"
|
label="Organization"
|
||||||
errorText={error?.message}
|
errorText={
|
||||||
isError={Boolean(error)}
|
integrationAuthOrgs?.length ? error?.message : "No organizations found"
|
||||||
>
|
}
|
||||||
<Select
|
isError={Boolean(integrationAuthOrgs?.length && error?.message)}
|
||||||
defaultValue={field.value}
|
|
||||||
onValueChange={(e) => onChange(e)}
|
|
||||||
className="w-full border border-mineshaft-500"
|
|
||||||
>
|
>
|
||||||
{integrationAuthOrgs && integrationAuthOrgs.map(({name, orgId}) => (
|
<Select
|
||||||
<SelectItem
|
defaultValue={field.value}
|
||||||
key={`github-organization-${orgId}`}
|
onValueChange={onChange}
|
||||||
value={orgId}
|
className="w-full border border-mineshaft-500"
|
||||||
>
|
>
|
||||||
{name}
|
{integrationAuthOrgs &&
|
||||||
</SelectItem>
|
integrationAuthOrgs.map(({ name, orgId }) => (
|
||||||
|
<SelectItem key={`github-organization-${orgId}`} value={orgId}>
|
||||||
))}
|
{name}
|
||||||
</Select>
|
</SelectItem>
|
||||||
</FormControl>
|
))}
|
||||||
)}
|
</Select>
|
||||||
/>
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{scope === "github-env" && (
|
{scope === "github-env" && (
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="repoId"
|
name="repoName"
|
||||||
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
||||||
<FormControl
|
<FormControl
|
||||||
label="Repositories"
|
label="Repository"
|
||||||
errorText={error?.message}
|
errorText={error?.message}
|
||||||
isError={Boolean(error)}
|
isError={Boolean(error)}
|
||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
defaultValue={field.value}
|
defaultValue={field.value}
|
||||||
onValueChange={(e) => onChange(e)}
|
onValueChange={(e) => {
|
||||||
|
setValue("repoName", e);
|
||||||
|
setValue(
|
||||||
|
"repoOwner",
|
||||||
|
(integrationAuthApps.find((app) => app.name === e)
|
||||||
|
?.owner as string) || ""
|
||||||
|
);
|
||||||
|
onChange(e);
|
||||||
|
}}
|
||||||
className="w-full border border-mineshaft-500"
|
className="w-full border border-mineshaft-500"
|
||||||
>
|
>
|
||||||
{integrationAuthApps.length > 0 ? (
|
{integrationAuthApps?.length ? (
|
||||||
integrationAuthApps.map((integrationAuthApp) => {
|
integrationAuthApps.map((app) => {
|
||||||
return (
|
return (
|
||||||
<SelectItem
|
<SelectItem
|
||||||
value={integrationAuthApp.appId as string}
|
value={app.name as string}
|
||||||
key={`repos-id-${integrationAuthApp.appId}`}
|
key={`repo-id-${app.appId}`}
|
||||||
className="w-[28.4rem] text-sm"
|
className="w-[28.4rem] text-sm"
|
||||||
>
|
>
|
||||||
{integrationAuthApp.name}
|
{app.name}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
) : (
|
) : (
|
||||||
<div />
|
<div />
|
||||||
)
|
)}
|
||||||
}
|
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
@@ -442,15 +486,33 @@ export default function GitHubCreateIntegrationPage() {
|
|||||||
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
||||||
<FormControl
|
<FormControl
|
||||||
label="Environment"
|
label="Environment"
|
||||||
errorText={error?.message}
|
errorText={
|
||||||
isError={Boolean(error)}
|
integrationAuthGithubEnvs?.length
|
||||||
|
? error?.message
|
||||||
|
: "No Environment found"
|
||||||
|
}
|
||||||
|
isError={Boolean(integrationAuthGithubEnvs?.length || error?.message)}
|
||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
defaultValue={field.value}
|
defaultValue={field.value}
|
||||||
onValueChange={(e) => onChange(e)}
|
onValueChange={onChange}
|
||||||
className="w-full border border-mineshaft-500"
|
className="w-full border border-mineshaft-500"
|
||||||
>
|
>
|
||||||
<SelectItem value="github-repo">Select Environment</SelectItem>
|
{integrationAuthGithubEnvs?.length ? (
|
||||||
|
integrationAuthGithubEnvs.map((githubEnv) => {
|
||||||
|
return (
|
||||||
|
<SelectItem
|
||||||
|
value={githubEnv.name as string}
|
||||||
|
key={`env-id-${githubEnv.envId}`}
|
||||||
|
className="w-[28.4rem] text-sm"
|
||||||
|
>
|
||||||
|
{githubEnv.name}
|
||||||
|
</SelectItem>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
) : (
|
||||||
|
<div />
|
||||||
|
)}
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
@@ -493,7 +555,6 @@ export default function GitHubCreateIntegrationPage() {
|
|||||||
variant="outline_bg"
|
variant="outline_bg"
|
||||||
className="mb-6"
|
className="mb-6"
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
isDisabled={integrationAuthApps.length === 0 || repoIds?.length === 0}
|
|
||||||
>
|
>
|
||||||
Create Integration
|
Create Integration
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
Reference in New Issue
Block a user