Skip to content

Commit 03893ab

Browse files
committed
Merge branch 'main' into feat/tb-partitioned-activityRelations
2 parents b5743df + 22ef34e commit 03893ab

File tree

38 files changed

+1028
-212
lines changed

38 files changed

+1028
-212
lines changed

backend/config/custom-environment-variables.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,6 @@
8484
"appId": "CROWD_SLACK_APP_ID",
8585
"appToken": "CROWD_SLACK_APP_TOKEN"
8686
},
87-
"slackNotifier": {
88-
"clientId": "CROWD_SLACK_NOTIFIER_CLIENT_ID",
89-
"clientSecret": "CROWD_SLACK_NOTIFIER_CLIENT_SECRET"
90-
},
9187
"google": {
9288
"clientId": "CROWD_GOOGLE_CLIENT_ID",
9389
"clientSecret": "CROWD_GOOGLE_CLIENT_SECRET",

backend/config/default.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
"slack": {
2727
"maxRetrospectInSeconds": 3600
2828
},
29-
"slackNotifier": {},
3029
"google": {},
3130
"discord": {
3231
"maxRetrospectInSeconds": 3600
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-- Remove stuckRequiresReOnboard column from git.repositories table
2+
-- Rollback for V1764675824__addStuckReOnboardColumnToGitRepositories.sql
3+
4+
ALTER TABLE git.repositories
5+
DROP COLUMN IF EXISTS "stuckRequiresReOnboard";
6+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-- Add stuckRequiresReOnboard column to git.repositories table
2+
-- This column indicates if a repository is stuck and requires re-onboarding
3+
4+
ALTER TABLE git.repositories
5+
ADD COLUMN "stuckRequiresReOnboard" BOOLEAN NOT NULL DEFAULT FALSE;
6+
7+
-- Add comment for documentation
8+
COMMENT ON COLUMN git.repositories."stuckRequiresReOnboard" IS 'Indicates if the stuck repository is resolved by a re-onboarding';
9+

backend/src/services/integrationService.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
startNangoSync,
2727
} from '@crowd/nango'
2828
import { RedisCache } from '@crowd/redis'
29-
import { WorkflowIdReusePolicy } from '@crowd/temporal'
29+
import { WorkflowIdConflictPolicy, WorkflowIdReusePolicy } from '@crowd/temporal'
3030
import { CodePlatform, Edition, PlatformType } from '@crowd/types'
3131

3232
import { IRepositoryOptions } from '@/database/repositories/IRepositoryOptions'
@@ -919,11 +919,12 @@ export default class IntegrationService {
919919
await this.options.temporal.workflow.start('syncGithubIntegration', {
920920
taskQueue: 'nango',
921921
workflowId: `github-nango-sync/${integration.id}`,
922-
workflowIdReusePolicy: WorkflowIdReusePolicy.WORKFLOW_ID_REUSE_POLICY_ALLOW_DUPLICATE,
922+
workflowIdReusePolicy: WorkflowIdReusePolicy.ALLOW_DUPLICATE,
923+
workflowIdConflictPolicy: WorkflowIdConflictPolicy.USE_EXISTING,
923924
retry: {
924925
maximumAttempts: 10,
925926
},
926-
args: [{ integrationIds: [integration.id] }],
927+
args: [{ integrationId: integration.id }],
927928
})
928929

929930
return await this.findById(integration.id)

frontend/src/modules/admin/modules/insights-projects/widgets.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ export enum Widgets {
2626
AVERAGE_TIME_TO_MERGE = 'averageTimeToMerge',
2727
WAIT_TIME_FOR_1ST_REVIEW = 'waitTimeFor1stReview',
2828
CODE_REVIEW_ENGAGEMENT = 'codeReviewEngagement',
29+
REVIEW_EFFICIENCY = 'reviewEfficiency',
30+
PATCHSET_PER_REVIEW = 'patchsetPerReview',
31+
MEDIAN_TIME_TO_MERGE = 'medianTimeToMerge',
32+
MEDIAN_TIME_TO_REVIEW = 'medianTimeToReview',
2933
}
3034

3135
export const WIDGETS_GROUPS = [
@@ -151,6 +155,22 @@ export const WIDGETS_GROUPS = [
151155
name: 'Code review engagement',
152156
key: Widgets.CODE_REVIEW_ENGAGEMENT,
153157
},
158+
{
159+
name: 'Review efficiency',
160+
key: Widgets.REVIEW_EFFICIENCY,
161+
},
162+
{
163+
name: 'Patchsets per review',
164+
key: Widgets.PATCHSET_PER_REVIEW,
165+
},
166+
{
167+
name: 'Median time to merge',
168+
key: Widgets.MEDIAN_TIME_TO_MERGE,
169+
},
170+
{
171+
name: 'Median time to review',
172+
key: Widgets.MEDIAN_TIME_TO_REVIEW,
173+
},
154174
],
155175
},
156176
];

pnpm-lock.yaml

Lines changed: 52 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

services/apps/cron_service/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"@crowd/data-access-layer": "workspace:*",
1818
"@crowd/logging": "workspace:*",
1919
"@crowd/nango": "workspace:*",
20+
"@crowd/slack": "workspace:*",
2021
"@crowd/temporal": "workspace:*",
2122
"@crowd/types": "workspace:*",
2223
"@crowd/common_services": "workspace:*",

services/apps/cron_service/src/jobs/nangoGithubSync.job.ts

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import CronTime from 'cron-time-generator'
22

3-
import { IS_DEV_ENV } from '@crowd/common'
3+
import { ConcurrencyLimiter, IS_DEV_ENV } from '@crowd/common'
44
import { READ_DB_CONFIG, getDbConnection } from '@crowd/data-access-layer/src/database'
55
import { fetchNangoIntegrationData } from '@crowd/data-access-layer/src/integrations'
66
import { pgpQx } from '@crowd/data-access-layer/src/queryExecutor'
77
import { NangoIntegration, nangoIntegrationToPlatform } from '@crowd/nango'
8-
import { TEMPORAL_CONFIG, WorkflowIdReusePolicy, getTemporalClient } from '@crowd/temporal'
8+
import {
9+
TEMPORAL_CONFIG,
10+
WorkflowIdConflictPolicy,
11+
WorkflowIdReusePolicy,
12+
getTemporalClient,
13+
} from '@crowd/temporal'
914
import { PlatformType } from '@crowd/types'
1015

1116
import { IJobDefinition } from '../types'
@@ -15,7 +20,7 @@ const job: IJobDefinition = {
1520
cronTime: CronTime.every(
1621
Number(process.env.CROWD_GH_NANGO_SYNC_INTERVAL_MINUTES || IS_DEV_ENV ? 5 : 60),
1722
).minutes(),
18-
timeout: 10 * 60,
23+
timeout: 4 * 60 * 60, // 4 hours
1924
process: async (ctx) => {
2025
ctx.log.info('Triggering nango API check as if a webhook was received!')
2126

@@ -27,9 +32,13 @@ const job: IJobDefinition = {
2732
nangoIntegrationToPlatform(NangoIntegration.GITHUB),
2833
])
2934

30-
const ids: string[] = []
35+
const limiter = new ConcurrencyLimiter(5)
3136

32-
for (const int of integrations) {
37+
// Collect all workflow start operations
38+
const workflowStarts: Array<() => Promise<void>> = []
39+
40+
for (let i = 0; i < integrations.length; i++) {
41+
const int = integrations[i]
3342
const { id, platform } = int
3443

3544
if (platform !== PlatformType.GITHUB_NANGO) {
@@ -40,22 +49,51 @@ const job: IJobDefinition = {
4049
{
4150
integrationId: id,
4251
},
43-
'Triggering nango github integration sync!',
52+
`${i + 1}/${integrations.length} Triggering nango github integration sync!`,
4453
)
4554

46-
ids.push(id)
55+
workflowStarts.push(async () => {
56+
await temporal.workflow
57+
.start('syncGithubIntegration', {
58+
taskQueue: 'nango',
59+
workflowId: `github-nango-sync/cron/${id}`,
60+
workflowIdReusePolicy: WorkflowIdReusePolicy.ALLOW_DUPLICATE,
61+
workflowIdConflictPolicy: WorkflowIdConflictPolicy.USE_EXISTING,
62+
retry: {
63+
maximumAttempts: 10,
64+
},
65+
args: [{ integrationId: id }],
66+
})
67+
.catch((err) =>
68+
ctx.log.error(err, 'Error while triggering nango github integration sync!'),
69+
)
70+
})
4771
}
4872

49-
await temporal.workflow.start('syncGithubIntegration', {
50-
taskQueue: 'nango',
51-
workflowId: `github-nango-sync/cron/${new Date().toISOString()}`,
52-
workflowIdReusePolicy:
53-
WorkflowIdReusePolicy.WORKFLOW_ID_REUSE_POLICY_ALLOW_DUPLICATE_FAILED_ONLY,
54-
retry: {
55-
maximumAttempts: 10,
56-
},
57-
args: [{ integrationIds: ids }],
73+
ctx.log.info(
74+
`Triggering nango github integration syncs with ${workflowStarts.length} workflows!`,
75+
)
76+
77+
// Track completed workflows
78+
let completedWorkflows = 0
79+
80+
// Register callback to track completed workflows
81+
limiter.setOnJobComplete(() => {
82+
completedWorkflows++
83+
if (completedWorkflows % 100 === 0) {
84+
ctx.log.info(`Triggered ${completedWorkflows} nango github integration syncs so far...`)
85+
}
5886
})
87+
88+
// Process all workflow starts with concurrency limit
89+
for (const workflowStart of workflowStarts) {
90+
await limiter.schedule(workflowStart)
91+
}
92+
93+
// Wait for all remaining jobs to complete
94+
await limiter.waitForFinish()
95+
96+
ctx.log.info(`Triggered ${completedWorkflows} nango github integration syncs in total`)
5997
},
6098
}
6199

0 commit comments

Comments
 (0)