Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -3,7 +3,10 @@ import { logger } from "../../../lib/logger";
import { DeploymentChangeType } from "@prisma/client";
import { hasChangedFilesInSubdirectory } from "./deployment-monorepo.service";
import { DataIntegrityException } from "../../errors/exceptions/data-integrity.exception";
import { linkPullRequestsToDeployment } from "./deployment-pr-linking.service";
import {
linkPullRequestsToDeployment,
updatePullRequestDeploymentTracking,
} from "./deployment-pr-linking.service";
import { CreateDeploymentFromPullRequestMergeArgs } from "./deployment-create-from-merge.types";
import { BusinessRuleException } from "../../errors/exceptions/business-rule.exception";

Expand Down Expand Up @@ -70,6 +73,12 @@ export const createDeploymentFromPullRequestMerge = async ({
pullRequestIds: [pullRequest.id],
});

await updatePullRequestDeploymentTracking({
pullRequest,
deployment,
workspaceId,
});

logger.info("deploymentCreateFromMergeWorker: Deployment created", {
deployment,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { Application, Environment, PullRequest } from "@prisma/client";
import {
Application,
Environment,
PullRequest,
PullRequestTracking,
} from "@prisma/client";

export interface CreateDeploymentFromPullRequestMergeArgs {
application: Application;
environment: Environment;
pullRequest: PullRequest;
pullRequest: PullRequest & { tracking: PullRequestTracking | null };
workspaceId: number;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import {
FilterPullRequestsBySubdirectoryArgs,
HasChangedFilesInSubdirectoryArgs,
} from "./deployment-monorepo.types";
import { PullRequest } from "@prisma/client";

export const filterPullRequestsBySubdirectory = ({
export const filterPullRequestsBySubdirectory = <T extends PullRequest>({
pullRequests,
subdirectory,
}: FilterPullRequestsBySubdirectoryArgs) => {
}: FilterPullRequestsBySubdirectoryArgs<T>) => {
if (!subdirectory) {
return pullRequests;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { PullRequest } from "@prisma/client";

export interface FilterPullRequestsBySubdirectoryArgs {
pullRequests: PullRequest[];
export interface FilterPullRequestsBySubdirectoryArgs<
T extends PullRequest = PullRequest,
> {
pullRequests: T[];
subdirectory?: string;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
HandleDeploymentPullRequestAutoLinkingArgs,
LinkPullRequestsToDeploymentArgs,
UpdateDeploymentChangeTypeInput,
UpdatePullRequestDeploymentTrackingArgs,
} from "./deployment-pr-linking.types";
import { logger } from "../../../lib/logger";
import { ResourceNotFoundException } from "../../errors/exceptions/resource-not-found.exception";
Expand All @@ -16,6 +17,9 @@ import {
findLatestDeployment,
} from "./deployment.service";
import { findWorkspaceById } from "../../workspaces/services/workspace.service";
import { getTimeToDeploy } from "../../github/services/github-pull-request-tracking.service";
import { DataIntegrityException } from "../../errors/exceptions/data-integrity.exception";
import { isBefore } from "date-fns";

export const handleDeploymentPullRequestAutoLinking = async ({
workspaceId,
Expand Down Expand Up @@ -103,7 +107,7 @@ export const handleDeploymentPullRequestAutoLinking = async ({
return;
}

const pullRequests = await findPullRequestsByCommitHashes({
const mergedPullRequests = await findMergedPullRequestsByCommitHashes({
workspaceId: workspaceId,
repositoryId: deployment.application.repositoryId,
commitHashes: commits,
Expand All @@ -113,8 +117,10 @@ export const handleDeploymentPullRequestAutoLinking = async ({
subdirectory?: string;
};

const filteredPullRequests = filterPullRequestsBySubdirectory({
pullRequests,
const filteredPullRequests = filterPullRequestsBySubdirectory<
(typeof mergedPullRequests)[number]
>({
pullRequests: mergedPullRequests,
subdirectory: deploymentSettings?.subdirectory,
});

Expand All @@ -124,19 +130,86 @@ export const handleDeploymentPullRequestAutoLinking = async ({
{
deploymentId: deploymentId,
workspaceId: workspaceId,
pullRequests,
pullRequests: mergedPullRequests,
subdirectory: deploymentSettings?.subdirectory,
}
);

return;
}

if (filteredPullRequests.some((pr) => !pr.mergedAt)) {
throw new DataIntegrityException(
"handleDeploymentPullRequestAutoLinking: Some PRs are not merged",
{
extra: { filteredPullRequests },
}
);
}

await linkPullRequestsToDeployment({
workspaceId: workspaceId,
deploymentId: deploymentId,
pullRequestIds: filteredPullRequests.map((pr) => pr.id),
});

await Promise.all(
filteredPullRequests.map(async (pr) => {
return updatePullRequestDeploymentTracking({
pullRequest: pr,
deployment,
workspaceId,
});
})
);
};

export const updatePullRequestDeploymentTracking = async ({
pullRequest,
deployment,
workspaceId,
}: UpdatePullRequestDeploymentTrackingArgs) => {
if (!pullRequest.mergedAt) {
throw new DataIntegrityException(
"[updatePullRequestDeploymentTracking] Depoloyed Pull Request is not merged",
Comment thread
waltergalvao marked this conversation as resolved.
Outdated
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
{
extra: { pullRequest },
}
);
}

const previousDeployedAt = pullRequest.tracking?.firstDeployedAt;

if (
previousDeployedAt &&
isBefore(previousDeployedAt, deployment.deployedAt)
) {
logger.info(
"[updatePullRequestDeploymentTracking] Previous deployment is earlier than this deployment. Skipping PR tracking update.",
{
previousDeployedAt,
deploymentDeployedAt: deployment.deployedAt,
pullRequest,
workspaceId,
}
);

return;
}

await getPrisma(workspaceId).pullRequestTracking.update({
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
where: {
pullRequestId: pullRequest.id,
workspaceId: workspaceId,
},
data: {
firstDeployedAt: deployment.deployedAt,
timeToDeploy: getTimeToDeploy(
pullRequest.mergedAt,
deployment.deployedAt
),
},
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.
};
Comment thread
waltergalvao marked this conversation as resolved.

const updateDeploymentToBaseline = async (
Expand Down Expand Up @@ -192,7 +265,7 @@ const getChangeTypeFromGitHubComparisonStatus = (
return statusToChangeTypeMap[status];
};

export const findPullRequestsByCommitHashes = async ({
export const findMergedPullRequestsByCommitHashes = async ({
workspaceId,
repositoryId,
commitHashes,
Expand All @@ -202,6 +275,7 @@ export const findPullRequestsByCommitHashes = async ({
mergeCommitSha: { in: commitHashes },
workspaceId,
repositoryId,
mergedAt: { not: null },
},
include: {
deploymentEvents: true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { DeploymentChangeType } from "@prisma/client";
import {
Deployment,
DeploymentChangeType,
PullRequest,
PullRequestTracking,
} from "@prisma/client";

export interface HandleDeploymentPullRequestAutoLinkingArgs {
workspaceId: number;
Expand Down Expand Up @@ -30,3 +35,9 @@ export interface LinkPullRequestsToDeploymentArgs {
deploymentId: number;
pullRequestIds: number[];
}

export interface UpdatePullRequestDeploymentTrackingArgs {
workspaceId: number;
pullRequest: PullRequest & { tracking: PullRequestTracking | null };
deployment: Pick<Deployment, "id" | "deployedAt">;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { PullRequest } from "@prisma/client";
import { Job } from "bullmq";
import { SweetQueue } from "../../../bull-mq/queues";
import { createWorker } from "../../../bull-mq/workers";
Expand All @@ -11,29 +10,41 @@ import {
import { ResourceNotFoundException } from "../../errors/exceptions/resource-not-found.exception";
import { findRepositoryById } from "../../repositories/services/repository.service";
import { createDeploymentFromPullRequestMerge } from "../services/deployment-create-from-merge.service";
import { findPullRequestById } from "../../pull-requests/services/pull-request.service";

interface DeploymentTriggeredByPullRequestMergeJobData {
workspaceId: number;
pullRequest: PullRequest;
pullRequestId: number;
installationId: string;
}

export const deploymentTriggeredByPullRequestMergeWorker = createWorker(
SweetQueue.DEPLOYMENT_TRIGGERED_BY_PULL_REQUEST_MERGE,
async (job: Job<DeploymentTriggeredByPullRequestMergeJobData>) => {
logger.info("deploymentTriggeredByPullRequestMergeWorker", {
data: job.data,
});
logger.info("deploymentTriggeredByPullRequestMergeWorker", job.data);

const workspaceId = job.data.workspaceId;
const pullRequest = job.data.pullRequest;
const { workspaceId, pullRequestId } = job.data;

if (!workspaceId) {
throw new ResourceNotFoundException("Workspace not found", {
extra: { data: job.data },
});
}

const pullRequest = await findPullRequestById({
workspaceId,
pullRequestId,
include: {
tracking: true,
},
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.

if (!pullRequest) {
throw new ResourceNotFoundException("Pull request not found", {
extra: { data: job.data },
});
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const repository = await findRepositoryById({
workspaceId,
repositoryId: pullRequest.repositoryId,
Expand Down Expand Up @@ -66,7 +77,7 @@ export const deploymentTriggeredByPullRequestMergeWorker = createWorker(
if (!pullRequest.mergedAt || !pullRequest.mergeCommitSha) {
logger.info(
"deploymentTriggeredByPullRequestMergeWorker: Pull request not merged",
{ data: job.data }
job.data
);

return;
Expand All @@ -75,7 +86,7 @@ export const deploymentTriggeredByPullRequestMergeWorker = createWorker(
if (!repository.applications?.length) {
logger.info(
"deploymentTriggeredByPullRequestMergeWorker: No applications found",
{ data: job.data }
job.data
);

return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,23 @@ export const getTimeToCode = (
*/
export const getTimeToMerge = (
pullRequest: PullRequest,
firstApprovalAt?: Date | null
firstApprovalAt?: Date | null,
firstReadyAt?: Date | null
) => {
const compareWith = firstApprovalAt || pullRequest.createdAt;
const compareWith = firstApprovalAt || firstReadyAt || pullRequest.createdAt;

if (!pullRequest.mergedAt) return undefined;

return differenceInBusinessMilliseconds(compareWith, pullRequest.mergedAt);
};

/**
* Time between the PR merge and being deployed
*/
export const getTimeToDeploy = (mergedAt: Date, deployedAt: Date) => {
return differenceInBusinessMilliseconds(mergedAt, deployedAt);
};

/**
* Time between the first commit and the PR being merged
*/
Expand Down
Loading
Loading