mirror of
https://github.com/moghtech/komodo.git
synced 2026-09-05 16:00:50 +00:00
build repo webhook management
This commit is contained in:
@@ -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<CreateBuildWebhook, User> for State {
|
||||
user: User,
|
||||
) -> anyhow::Result<CreateBuildWebhookResponse> {
|
||||
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::<Build>(
|
||||
@@ -149,6 +154,22 @@ impl Resolve<CreateBuildWebhook, User> 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<DeleteBuildWebhook, User> for State {
|
||||
user: User,
|
||||
) -> anyhow::Result<DeleteBuildWebhookResponse> {
|
||||
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::<Build>(
|
||||
|
||||
@@ -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<CreateRepoWebhook, User> 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 {})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Partial<Types.BuildConfig>>({});
|
||||
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) && (
|
||||
// <AccountSelector
|
||||
// id={update.builder_id ?? config.builder_id ?? undefined}
|
||||
// type="Builder"
|
||||
// account_type="docker"
|
||||
// selected={account}
|
||||
// onSelect={(docker_account) => set({ docker_account })}
|
||||
// disabled={disabled}
|
||||
// placeholder="None"
|
||||
// />
|
||||
// ),
|
||||
// docker_organization:
|
||||
// docker_organizations === undefined ||
|
||||
// docker_organizations.length === 0
|
||||
// ? undefined
|
||||
// : (value, set) => (
|
||||
// <DockerOrganizations
|
||||
// value={value}
|
||||
// set={set}
|
||||
// disabled={disabled}
|
||||
// />
|
||||
// ),
|
||||
use_buildx: true,
|
||||
},
|
||||
},
|
||||
@@ -251,11 +231,75 @@ export const BuildConfig = ({
|
||||
label: "Github Webhook",
|
||||
components: {
|
||||
["build" as any]: () => (
|
||||
<ConfigItem label="Build">
|
||||
<ConfigItem label="Webhook Url">
|
||||
<CopyGithubWebhook path={`/build/${id}`} />
|
||||
</ConfigItem>
|
||||
),
|
||||
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 (
|
||||
<ConfigItem label="Manage Webhook">
|
||||
{webhook.enabled && (
|
||||
<div className="flex items-center gap-4 flex-wrap">
|
||||
<div className="flex items-center gap-2">
|
||||
Incoming webhook is{" "}
|
||||
<div
|
||||
className={text_color_class_by_intention("Good")}
|
||||
>
|
||||
enabled
|
||||
</div>
|
||||
</div>
|
||||
<ConfirmButton
|
||||
title="Disable"
|
||||
icon={<Ban className="w-4 h-4" />}
|
||||
variant="destructive"
|
||||
onClick={() => deleteWebhook({ build: id })}
|
||||
loading={deletePending}
|
||||
disabled={disabled || deletePending}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{!webhook.enabled && (
|
||||
<div className="flex items-center gap-4 flex-wrap">
|
||||
<div className="flex items-center gap-2">
|
||||
Incoming webhook is{" "}
|
||||
<div
|
||||
className={text_color_class_by_intention(
|
||||
"Critical"
|
||||
)}
|
||||
>
|
||||
disabled
|
||||
</div>
|
||||
</div>
|
||||
<ConfirmButton
|
||||
title="Enable"
|
||||
icon={<CirclePlus className="w-4 h-4" />}
|
||||
onClick={() => createWebhook({ build: id })}
|
||||
loading={createPending}
|
||||
disabled={disabled || createPending}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</ConfigItem>
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user