Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import { Configuration } from "@gitpod/public-api/lib/gitpod/v1/configuration_pb
import { ConfigurationSettingsField } from "./ConfigurationSettingsField";
import { Heading3, Subheading } from "@podkit/typography/Headings";
import { SwitchInputField } from "@podkit/switch/Switch";
import { TextMuted } from "@podkit/typography/TextMuted";
import { PrebuildSettingsForm } from "./prebuilds/PrebuildSettingsForm";
import { useConfigurationMutation } from "../../data/configurations/configuration-queries";
import { LoadingState } from "@podkit/loading/LoadingState";
import { EnablePrebuildsError } from "./prebuilds/EnablePrebuildsError";
import { TextMuted } from "@podkit/typography/TextMuted";
import { Link } from "react-router-dom";

type Props = {
Expand Down Expand Up @@ -68,21 +68,9 @@ export const ConfigurationDetailPrebuilds: FC<Props> = ({ configuration }) => {
label={configuration.prebuildSettings?.enabled ? "Prebuilds are enabled" : "Prebuilds are disabled"}
description={
<TextMuted>
Enabling requires permissions to configure repository webhooks.{" "}
<a
href="https://www.gitpod.io/docs/configure/repositories/prebuilds"
className="gp-link"
target="_blank"
rel="noopener noreferrer"
>
Learn more
</a>
.
<br />
<Link to={`/prebuilds?configurationId=${configuration.id}`} className="gp-link">
View prebuild history
</Link>
.
</TextMuted>
}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
* See License.AGPL.txt in the project root for license information.
*/

import { BranchMatchingStrategy, Configuration } from "@gitpod/public-api/lib/gitpod/v1/configuration_pb";
import { FC, FormEvent, useCallback, useState } from "react";
import {
BranchMatchingStrategy,
Configuration,
PrebuildTriggerStrategy,
} from "@gitpod/public-api/lib/gitpod/v1/configuration_pb";
import { FC, FormEvent, useCallback, useMemo, useState } from "react";
import { ConfigurationSettingsField } from "../ConfigurationSettingsField";
import { Heading3, Subheading } from "@podkit/typography/Headings";
import { InputField } from "../../../components/forms/InputField";
Expand All @@ -17,15 +21,26 @@ import { LoadingButton } from "@podkit/buttons/LoadingButton";
import { InputFieldHint } from "../../../components/forms/InputFieldHint";
import { DEFAULT_WS_CLASS } from "../../../data/workspaces/workspace-classes-query";
import { Select, SelectItem, SelectTrigger, SelectValue, SelectContent } from "@podkit/select/Select";
import Alert from "../../../components/Alert";
import { useUserLoader } from "../../../hooks/use-user-loader";
import { useUpdateCurrentUserMutation } from "../../../data/current-user/update-mutation";
import { trackEvent } from "../../../Analytics";
import dayjs from "dayjs";

const DEFAULT_PREBUILD_COMMIT_INTERVAL = 20;

type Props = {
configuration: Configuration;
};

const COACHMARK_KEY = "new_prebuilds_trigger_notification";
Copy link
Member Author

@filiptronicek filiptronicek Jul 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not really a coach mark, but I for some reason couldn't imagine coachmarksDismissals being used for anything else in #19413 🤦

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, hindsight's 20/20


export const PrebuildSettingsForm: FC<Props> = ({ configuration }) => {
const { toast } = useToast();

const { user } = useUserLoader();
const { mutate: updateUser } = useUpdateCurrentUserMutation();

const updateConfiguration = useConfigurationMutation();

const [interval, setInterval] = useState<string>(
Expand All @@ -41,6 +56,8 @@ export const PrebuildSettingsForm: FC<Props> = ({ configuration }) => {
configuration.prebuildSettings?.workspaceClass || DEFAULT_WS_CLASS,
);

const [isTriggerNotificationOpen, setIsTriggerNotificationOpen] = useState(true);

const handleSubmit = useCallback(
(e: FormEvent) => {
e.preventDefault();
Expand Down Expand Up @@ -83,8 +100,61 @@ export const PrebuildSettingsForm: FC<Props> = ({ configuration }) => {
setBranchStrategy(parseInt(val, 10) as BranchMatchingStrategy);
}, []);

const dismissNotification = useCallback(() => {
updateUser(
{
additionalData: { profile: { coachmarksDismissals: { [COACHMARK_KEY]: dayjs().toISOString() } } },
},
{
onSettled: (_, error) => {
trackEvent("coachmark_dismissed", {
name: COACHMARK_KEY,
success: !(error instanceof Error),
});
setIsTriggerNotificationOpen(false);
},
},
);
}, [updateUser]);

const showTriggerNotification = useMemo<boolean>(() => {
if (!isTriggerNotificationOpen || !user) {
return false;
}

if (configuration.prebuildSettings?.triggerStrategy === PrebuildTriggerStrategy.ACTIVITY_BASED) {
return false;
}

// For repositories created after activity-based prebuilds were introduced, don't show it
if (configuration.creationTime && configuration.creationTime.toDate() > new Date("7/15/2024")) {
return false;
}

return !user.profile?.coachmarksDismissals[COACHMARK_KEY];
}, [configuration.creationTime, configuration.prebuildSettings?.triggerStrategy, isTriggerNotificationOpen, user]);

return (
<ConfigurationSettingsField>
{showTriggerNotification && (
<Alert
type={"info"}
closable={true}
onClose={() => dismissNotification()}
showIcon={true}
className="flex rounded p-2 mb-2 w-full"
>
The way prebuilds are triggered is changing.{" "}
<a
className="gp-link"
target="_blank"
href="https://www.gitpod.io/changelog/activity-based-prebuilds"
rel="noreferrer"
>
Learn more
</a>
</Alert>
)}
<form onSubmit={handleSubmit}>
<Heading3>Prebuild settings</Heading3>
<Subheading className="max-w-lg">These settings will be applied on every Prebuild.</Subheading>
Expand Down
7 changes: 7 additions & 0 deletions components/gitpod-protocol/src/teams-projects-protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface ProjectSettings {
}
export namespace PrebuildSettings {
export type BranchStrategy = "default-branch" | "all-branches" | "matched-branches";
export type TriggerStrategy = "activity-based" | "webhook-based";
}

export interface PrebuildSettings {
Expand All @@ -55,6 +56,11 @@ export interface PrebuildSettings {
* Preferred workspace class for prebuilds.
*/
workspaceClass?: string;

/**
* The activation strategy for prebuilds. Defaults to "webhook-based"
*/
triggerStrategy?: PrebuildSettings.TriggerStrategy;
}

export interface Project {
Expand Down Expand Up @@ -88,6 +94,7 @@ export namespace Project {
branchMatchingPattern: "**",
prebuildInterval: 20,
branchStrategy: "all-branches",
triggerStrategy: "activity-based",
};

/**
Expand Down
9 changes: 9 additions & 0 deletions components/public-api/gitpod/v1/configuration.proto
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,20 @@ message Configuration {
WorkspaceSettings workspace_settings = 7;
}

enum PrebuildTriggerStrategy {
// Default value. Implicitly applies to webhoook-based activation
PREBUILD_TRIGGER_STRATEGY_UNSPECIFIED = 0;
// Default value for newly enabled prebuilds.
PREBUILD_TRIGGER_STRATEGY_ACTIVITY_BASED = 1;
}

message PrebuildSettings {
bool enabled = 1;
string branch_matching_pattern = 2;
BranchMatchingStrategy branch_strategy = 3;
int32 prebuild_interval = 4;
string workspace_class = 5;
PrebuildTriggerStrategy trigger_strategy = 6;
}

enum BranchMatchingStrategy {
Expand Down Expand Up @@ -97,6 +105,7 @@ message UpdateConfigurationRequest {
optional BranchMatchingStrategy branch_strategy = 3;
optional int32 prebuild_interval = 4;
optional string workspace_class = 5;
optional PrebuildTriggerStrategy trigger_strategy = 6;
}
message WorkspaceSettings {
optional string workspace_class = 1;
Expand Down
Loading