From 78a63f92bb42c7b7c1e70c6ea034cd1909eb8385 Mon Sep 17 00:00:00 2001 From: mbecker20 Date: Fri, 5 Jul 2024 03:17:29 -0700 Subject: [PATCH] build repo webhook management --- bin/core/src/api/write/build.rs | 31 +++++- bin/core/src/api/write/repo.rs | 23 +++- .../src/components/resources/build/config.tsx | 100 +++++++++++++----- 3 files changed, 120 insertions(+), 34 deletions(-) diff --git a/bin/core/src/api/write/build.rs b/bin/core/src/api/write/build.rs index 396de8c92..f5a1b32a5 100644 --- a/bin/core/src/api/write/build.rs +++ b/bin/core/src/api/write/build.rs @@ -2,8 +2,11 @@ use anyhow::{anyhow, Context}; use monitor_client::{ api::write::*, entities::{ - build::Build, config::core::CoreConfig, - permission::PermissionLevel, user::User, NoData, + build::{Build, PartialBuildConfig}, + config::core::CoreConfig, + permission::PermissionLevel, + user::User, + NoData, }, }; use octorust::types::{ @@ -76,7 +79,9 @@ impl Resolve for State { user: User, ) -> anyhow::Result { let Some(github) = github_client() else { - return Err(anyhow!("github_webhook_app is not configured in core config toml")); + return Err(anyhow!( + "github_webhook_app is not configured in core config toml" + )); }; let build = resource::get_check_permissions::( @@ -149,6 +154,22 @@ impl Resolve for State { .await .context("failed to create webhook")?; + if !build.config.webhook_enabled { + self + .resolve( + UpdateBuild { + id: build.id, + config: PartialBuildConfig { + webhook_enabled: Some(true), + ..Default::default() + }, + }, + user, + ) + .await + .context("failed to update build to enable webhook")?; + } + Ok(NoData {}) } } @@ -161,7 +182,9 @@ impl Resolve for State { user: User, ) -> anyhow::Result { let Some(github) = github_client() else { - return Err(anyhow!("github_webhook_app is not configured in core config toml")); + return Err(anyhow!( + "github_webhook_app is not configured in core config toml" + )); }; let build = resource::get_check_permissions::( diff --git a/bin/core/src/api/write/repo.rs b/bin/core/src/api/write/repo.rs index e665e8966..02ba4c9a6 100644 --- a/bin/core/src/api/write/repo.rs +++ b/bin/core/src/api/write/repo.rs @@ -2,8 +2,11 @@ use anyhow::{anyhow, Context}; use monitor_client::{ api::write::*, entities::{ - config::core::CoreConfig, permission::PermissionLevel, - repo::Repo, user::User, NoData, + config::core::CoreConfig, + permission::PermissionLevel, + repo::{PartialRepoConfig, Repo}, + user::User, + NoData, }, }; use octorust::types::{ @@ -158,6 +161,22 @@ impl Resolve for State { .await .context("failed to create webhook")?; + if !repo.config.webhook_enabled { + self + .resolve( + UpdateRepo { + id: repo.id, + config: PartialRepoConfig { + webhook_enabled: Some(true), + ..Default::default() + }, + }, + user, + ) + .await + .context("failed to update repo to enable webhook")?; + } + Ok(NoData {}) } } diff --git a/frontend/src/components/resources/build/config.tsx b/frontend/src/components/resources/build/config.tsx index 6bee9a289..f1be9cd2a 100644 --- a/frontend/src/components/resources/build/config.tsx +++ b/frontend/src/components/resources/build/config.tsx @@ -8,14 +8,17 @@ import { SecretSelector, SystemCommand, } from "@components/config/util"; -import { useRead, useWrite } from "@lib/hooks"; +import { useInvalidate, useRead, useWrite } from "@lib/hooks"; import { env_to_text } from "@lib/utils"; import { Types } from "@monitor/client"; import { Button } from "@ui/button"; import { Textarea } from "@ui/textarea"; -import { PlusCircle } from "lucide-react"; +import { Ban, CirclePlus, PlusCircle } from "lucide-react"; import { ReactNode, RefObject, createRef, useState } from "react"; import { CopyGithubWebhook, LabelsConfig, ResourceSelector } from "../common"; +import { useToast } from "@ui/use-toast"; +import { text_color_class_by_intention } from "@lib/color"; +import { ConfirmButton } from "@components/util"; export const BuildConfig = ({ id, @@ -28,9 +31,9 @@ export const BuildConfig = ({ target: { type: "Build", id }, }).data; const config = useRead("GetBuild", { build: id }).data?.config; + const webhook = useRead("GetBuildWebhookEnabled", { build: id }).data; const global_disabled = useRead("GetCoreInfo", {}).data?.ui_write_disabled ?? false; - // const docker_organizations = useRead("ListDockerOrganizations", {}).data; const [update, set] = useState>({}); const { mutateAsync } = useWrite("UpdateBuild"); @@ -145,29 +148,6 @@ export const BuildConfig = ({ }, build_path: true, dockerfile_path: true, - // docker_account: (account, set) => - // (update.builder_id ?? config.builder_id ? true : false) && ( - // set({ docker_account })} - // disabled={disabled} - // placeholder="None" - // /> - // ), - // docker_organization: - // docker_organizations === undefined || - // docker_organizations.length === 0 - // ? undefined - // : (value, set) => ( - // - // ), use_buildx: true, }, }, @@ -251,11 +231,75 @@ export const BuildConfig = ({ label: "Github Webhook", components: { ["build" as any]: () => ( - + ), - webhook_enabled: true, + webhook_enabled: webhook !== undefined && !webhook.managed, + ["managed" as any]: () => { + const inv = useInvalidate(); + const { toast } = useToast(); + const { mutate: createWebhook, isPending: createPending } = + useWrite("CreateBuildWebhook", { + onSuccess: () => { + toast({ title: "Webhook Created" }); + inv(["GetBuildWebhookEnabled", { build: id }]); + }, + }); + const { mutate: deleteWebhook, isPending: deletePending } = + useWrite("DeleteBuildWebhook", { + onSuccess: () => { + toast({ title: "Webhook Deleted" }); + inv(["GetBuildWebhookEnabled", { build: id }]); + }, + }); + if (!webhook || !webhook.managed) return; + return ( + + {webhook.enabled && ( +
+
+ Incoming webhook is{" "} +
+ enabled +
+
+ } + variant="destructive" + onClick={() => deleteWebhook({ build: id })} + loading={deletePending} + disabled={disabled || deletePending} + /> +
+ )} + {!webhook.enabled && ( +
+
+ Incoming webhook is{" "} +
+ disabled +
+
+ } + onClick={() => createWebhook({ build: id })} + loading={createPending} + disabled={disabled || createPending} + /> +
+ )} +
+ ); + }, }, }, ],