Skip to content

Commit 2f2f5f0

Browse files
committed
[projects] add message: Prebuilds have been paused
1 parent c5e353d commit 2f2f5f0

File tree

5 files changed

+36
-9
lines changed

5 files changed

+36
-9
lines changed

Diff for: components/dashboard/src/projects/Project.tsx

+17
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import Spinner from "../icons/Spinner.svg";
1818
import NoAccess from "../icons/NoAccess.svg";
1919
import { ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error";
2020
import { openAuthorizeWindow } from "../provider-utils";
21+
import Alert from "../components/Alert";
2122

2223
export default function () {
2324
const location = useLocation();
@@ -34,6 +35,7 @@ export default function () {
3435
const [isLoading, setIsLoading] = useState<boolean>(false);
3536
const [isLoadingBranches, setIsLoadingBranches] = useState<boolean>(false);
3637
const [branches, setBranches] = useState<Project.BranchDetails[]>([]);
38+
const [isConsideredInactive, setIsConsideredInactive] = useState<boolean>(false);
3739
const [prebuilds, setPrebuilds] = useState<Map<string, PrebuildWithStatus | undefined>>(new Map());
3840
const [prebuildLoaders] = useState<Set<string>>(new Set());
3941

@@ -91,6 +93,7 @@ export default function () {
9193
// default branch on top of the rest
9294
const branches = details.branches.sort((a, b) => (b.isDefault as any) - (a.isDefault as any)) || [];
9395
setBranches(branches);
96+
setIsConsideredInactive(details.prebuildState === "suspended_on_inactivity");
9497
}
9598
} finally {
9699
setIsLoadingBranches(false);
@@ -259,6 +262,20 @@ export default function () {
259262
<span>Prebuild</span>
260263
</ItemField>
261264
</Item>
265+
{isConsideredInactive && (
266+
<Alert
267+
type={"warning"}
268+
onClose={() => {}}
269+
showIcon={true}
270+
className="flex rounded mb-2 w-full"
271+
>
272+
Prebuilds have been paused for this projects because no workspaces have been opened
273+
for the past 7+ days.{" "}
274+
<a className="gp-link hover:text-gray-600" onClick={() => {}}>
275+
Resume prebuilds
276+
</a>
277+
</Alert>
278+
)}
262279
{isLoadingBranches && (
263280
<div className="flex items-center justify-center space-x-2 text-gray-400 text-sm pt-16 pb-40">
264281
<img className="h-4 w-4 animate-spin" src={Spinner} />

Diff for: components/gitpod-protocol/src/teams-projects-protocol.ts

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export namespace Project {
4545

4646
export interface Overview {
4747
branches: BranchDetails[];
48+
prebuildState?: "suspended_on_inactivity" | "enabled";
4849
}
4950

5051
export namespace Overview {

Diff for: components/server/ee/src/prebuilds/prebuild-manager.ts

+1-8
Original file line numberDiff line numberDiff line change
@@ -394,14 +394,7 @@ export class PrebuildManager {
394394
}
395395

396396
private async shouldSkipInactiveProject(project: Project): Promise<boolean> {
397-
const usage = await this.projectService.getProjectUsage(project.id);
398-
if (!usage?.lastWorkspaceStart) {
399-
return false;
400-
}
401-
const now = Date.now();
402-
const lastUse = new Date(usage.lastWorkspaceStart).getTime();
403-
const inactiveProjectTime = 1000 * 60 * 60 * 24 * 7 * 1; // 1 week
404-
return now - lastUse > inactiveProjectTime;
397+
return await this.projectService.isProjectConsideredInactive(project.id);
405398
}
406399

407400
private async shouldSkipInactiveRepository(ctx: TraceContext, cloneURL: string): Promise<boolean> {

Diff for: components/server/src/projects/projects-service.ts

+11
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,17 @@ export class ProjectsService {
279279
return this.projectDB.getProjectUsage(projectId);
280280
}
281281

282+
async isProjectConsideredInactive(projectId: string): Promise<boolean> {
283+
const usage = await this.getProjectUsage(projectId);
284+
if (!usage?.lastWorkspaceStart) {
285+
return false;
286+
}
287+
const now = Date.now();
288+
const lastUse = new Date(usage.lastWorkspaceStart).getTime();
289+
const inactiveProjectTime = 1000 * 60 * 60 * 24 * 7 * 1; // 1 week
290+
return now - lastUse > inactiveProjectTime;
291+
}
292+
282293
async getPrebuildEvents(cloneUrl: string): Promise<PrebuildEvent[]> {
283294
const events = await this.webhookEventDB.findByCloneUrl(cloneUrl, 100);
284295
return events.map((we) => ({

Diff for: components/server/src/workspace/gitpod-server-impl.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -2345,7 +2345,12 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
23452345
}
23462346
await this.guardProjectOperation(user, projectId, "get");
23472347
try {
2348-
return await this.projectsService.getProjectOverviewCached(user, project);
2348+
const result = await this.projectsService.getProjectOverviewCached(user, project);
2349+
if (result) {
2350+
const isProjectConsideredInactive = await this.projectsService.isProjectConsideredInactive(project.id);
2351+
result.prebuildState = isProjectConsideredInactive ? "suspended_on_inactivity" : "enabled";
2352+
}
2353+
return result;
23492354
} catch (error) {
23502355
if (UnauthorizedError.is(error)) {
23512356
throw new ResponseError(ErrorCodes.NOT_AUTHENTICATED, "Unauthorized", error.data);

0 commit comments

Comments
 (0)