Canvas: Github repository picker
Change-Id: Icb8f2ffbef2894b2fdea4e4c13c74c0f4970506b
diff --git a/apps/canvas/back/index.ts b/apps/canvas/back/index.ts
index 258bad9..cdcf9a0 100644
--- a/apps/canvas/back/index.ts
+++ b/apps/canvas/back/index.ts
@@ -2,6 +2,7 @@
import express from "express";
import { env } from "node:process";
import axios from "axios";
+import { GithubClient } from "./github";
const db = new PrismaClient();
@@ -134,7 +135,7 @@
where: {
id: projectId,
},
- });
+ });
}
resp.status(200);
} catch (e) {
@@ -155,6 +156,8 @@
},
select: {
instanceId: true,
+ githubToken: true,
+ deployKey: true,
},
});
if (p === null) {
@@ -178,6 +181,7 @@
config: req.body.config,
},
});
+ console.log(r);
if (r.status === 200) {
await db.project.update({
where: {
@@ -190,6 +194,20 @@
deployKey: r.data.deployKey,
},
});
+
+ if (p.githubToken && r.data.deployKey) {
+ const stateObj = JSON.parse(JSON.parse(state.toString()));
+ const githubNodes = stateObj.nodes.filter((n: any) => n.type === "github" && n.data?.repository?.id);
+
+ const github = new GithubClient(p.githubToken);
+ for (const node of githubNodes) {
+ try {
+ await github.addDeployKey(node.data.repository.sshURL, r.data.deployKey);
+ } catch (error) {
+ console.error(`Failed to add deploy key to repository ${node.data.repository.sshURL}:`, error);
+ }
+ }
+ }
}
} else {
r = await axios.request({
@@ -255,6 +273,94 @@
}
};
+const handleGithubRepos: express.Handler = async (req, resp) => {
+ try {
+ const projectId = Number(req.params["projectId"]);
+ const project = await db.project.findUnique({
+ where: { id: projectId },
+ select: { githubToken: true }
+ });
+
+ if (!project?.githubToken) {
+ resp.status(400);
+ resp.write(JSON.stringify({ error: "GitHub token not configured" }));
+ return;
+ }
+
+ const github = new GithubClient(project.githubToken);
+ const repositories = await github.getRepositories();
+
+ resp.status(200);
+ resp.header("Content-Type", "application/json");
+ resp.write(JSON.stringify(repositories));
+ } catch (e) {
+ console.log(e);
+ resp.status(500);
+ resp.write(JSON.stringify({ error: "Failed to fetch repositories" }));
+ } finally {
+ resp.end();
+ }
+};
+
+const handleUpdateGithubToken: express.Handler = async (req, resp) => {
+ try {
+ const projectId = Number(req.params["projectId"]);
+ const { githubToken } = req.body;
+
+ await db.project.update({
+ where: { id: projectId },
+ data: { githubToken },
+ });
+
+ resp.status(200);
+ } catch (e) {
+ console.log(e);
+ resp.status(500);
+ } finally {
+ resp.end();
+ }
+};
+
+const handleEnv: express.Handler = async (req, resp) => {
+ const projectId = Number(req.params["projectId"]);
+ try {
+ const project = await db.project.findUnique({
+ where: { id: projectId },
+ select: {
+ deployKey: true,
+ githubToken: true
+ }
+ });
+
+ if (!project) {
+ resp.status(404);
+ resp.write(JSON.stringify({ error: "Project not found" }));
+ return;
+ }
+
+ resp.status(200);
+ resp.write(JSON.stringify({
+ deployKey: project.deployKey,
+ integrations: {
+ github: !!project.githubToken,
+ },
+ networks: [{
+ name: "Public",
+ domain: "v1.dodo.cloud",
+ }, {
+ name: "Private",
+ domain: "p.v1.dodo.cloud",
+ }]
+ }));
+ } catch (error) {
+ console.error("Error checking integrations:", error);
+ resp.status(500);
+ resp.write(JSON.stringify({ error: "Internal server error" }));
+ } finally {
+ resp.end();
+ }
+};
+
async function start() {
await db.$connect();
const app = express();
@@ -266,6 +372,9 @@
app.delete("/api/project/:projectId", handleDelete);
app.get("/api/project", handleProjectAll);
app.post("/api/project", handleProjectCreate);
+ app.get("/api/project/:projectId/repos/github", handleGithubRepos);
+ app.post("/api/project/:projectId/github-token", handleUpdateGithubToken);
+ app.get("/api/project/:projectId/env", handleEnv);
app.use("/", express.static("../front/dist"));
app.listen(env.DODO_PORT_WEB, () => {
console.log("started");