Skip to content

Commit 057569a

Browse files
authored
Send event timestamp when triggering Git sync imports and exports (#335)
* Update triggerImport & triggerExport to pass the event timestamp to the API request * Pass revision created date as event timestamp when trigger export * Pass head commit timestamp on push as event timestamp when trigger github import * Pass head pr timestamp on pr webhooks when triggering github import * Pass head mr timestamp on mr webhooks when triggering gitlab import * Pass head commit timestamp on push event when triggering gitlab import * Review: rename eventCreatedAt to eventTimestamp * Do not send event timestamp for imports of merge/pull requests previews * Update after merge * Slighly safer checks
1 parent a7a3c37 commit 057569a

File tree

10 files changed

+90
-9
lines changed

10 files changed

+90
-9
lines changed

integrations/github/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,9 @@ const handleSpaceContentUpdated: EventCallback<
409409
return;
410410
}
411411

412-
await triggerExport(context, spaceInstallation);
412+
await triggerExport(context, spaceInstallation, {
413+
eventTimestamp: new Date(revision.createdAt),
414+
});
413415
};
414416

415417
/*

integrations/github/src/sync.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,18 @@ export async function triggerImport(
4343

4444
/** Whether the git info should be updated on the space */
4545
updateGitInfo?: boolean;
46+
47+
/**
48+
* The timestamp of the event that triggers the import.
49+
*
50+
* This is to help ensures that Git sync import and export operations are executed
51+
* in the same order on GitBook and on the remote repository.
52+
*/
53+
eventTimestamp?: Date;
4654
} = {}
4755
) {
4856
const { api } = context;
49-
const { force = false, updateGitInfo = false, standalone } = options;
57+
const { force = false, updateGitInfo = false, standalone, eventTimestamp } = options;
5058

5159
const config = getSpaceConfigOrThrow(spaceInstallation);
5260
assertIsDefined(config.branch, { label: 'config.branch' });
@@ -68,6 +76,7 @@ export async function triggerImport(
6876
repoProjectDirectory: config.projectDirectory,
6977
repoCacheID: config.key,
7078
force,
79+
timestamp: eventTimestamp && !force ? eventTimestamp.toISOString() : undefined,
7180
standalone: !!standalone,
7281
...(updateGitInfo ? { gitInfo: { provider: 'github', url: repoURL } } : {}),
7382
});
@@ -85,10 +94,18 @@ export async function triggerExport(
8594

8695
/** Whether the git info should be updated on the space */
8796
updateGitInfo?: boolean;
97+
98+
/**
99+
* The timestamp of the event that triggers the export.
100+
*
101+
* This is to help ensures that Git sync import and export operations are executed
102+
* in the same order on GitBook and on the remote repository.
103+
*/
104+
eventTimestamp?: Date;
88105
} = {}
89106
) {
90107
const { api } = context;
91-
const { force = false, updateGitInfo = false } = options;
108+
const { force = false, updateGitInfo = false, eventTimestamp } = options;
92109

93110
const config = getSpaceConfigOrThrow(spaceInstallation);
94111
assertIsDefined(config.branch, { label: 'config.branch' });
@@ -112,6 +129,7 @@ export async function triggerExport(
112129
repoProjectDirectory: config.projectDirectory,
113130
repoCacheID: config.key,
114131
force,
132+
timestamp: eventTimestamp && !force ? eventTimestamp.toISOString() : undefined,
115133
commitMessage: getCommitMessageForRevision(config, revision),
116134
...(updateGitInfo ? { gitInfo: { provider: 'github', url: repoURL } } : {}),
117135
});

integrations/github/src/tasks.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export async function handleImportDispatchForSpaces(
5050
context: GithubRuntimeContext,
5151
payload: IntegrationTaskImportSpaces['payload']
5252
): Promise<number | undefined> {
53-
const { configQuery, page, standaloneRef } = payload;
53+
const { configQuery, page, standaloneRef, eventTimestamp } = payload;
5454

5555
logger.debug(`handling import dispatch for spaces with payload: ${JSON.stringify(payload)}`);
5656

@@ -92,6 +92,7 @@ export async function handleImportDispatchForSpaces(
9292
ref: standaloneRef,
9393
}
9494
: undefined,
95+
eventTimestamp,
9596
});
9697
} catch (error) {
9798
logger.error(

integrations/github/src/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ export type IntegrationTaskImportSpaces = BaseIntegrationTask<
9393
configQuery: string;
9494
page?: string;
9595
standaloneRef?: string;
96+
/**
97+
* The timestamp of the event that triggers the export.
98+
*
99+
* This is to help ensures that Git sync import and export operations are executed
100+
* in the same order on GitBook and on the remote repository.
101+
*/
102+
eventTimestamp?: Date;
96103
}
97104
>;
98105

integrations/github/src/webhooks.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ export async function handlePushEvent(
6565

6666
const total = await handleImportDispatchForSpaces(context, {
6767
configQuery: queryKey,
68+
eventTimestamp: payload.head_commit?.timestamp
69+
? new Date(payload.head_commit.timestamp)
70+
: undefined,
6871
});
6972

7073
logger.debug(`${total} space configurations are affected`);

integrations/gitlab/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,9 @@ const handleSpaceContentUpdated: EventCallback<
322322
return;
323323
}
324324

325-
await triggerExport(context, spaceInstallation);
325+
await triggerExport(context, spaceInstallation, {
326+
eventTimestamp: new Date(revision.createdAt),
327+
});
326328
};
327329

328330
/*

integrations/gitlab/src/sync.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,18 @@ export async function triggerImport(
4343

4444
/** Whether the git info should be updated on the space */
4545
updateGitInfo?: boolean;
46+
47+
/**
48+
* The timestamp of the event that triggers the import.
49+
*
50+
* This is to help ensures that Git sync import and export operations are executed
51+
* in the same order on GitBook and on the remote repository.
52+
*/
53+
eventTimestamp?: Date;
4654
} = {}
4755
) {
4856
const { api } = context;
49-
const { force = false, updateGitInfo = false, standalone } = options;
57+
const { force = false, updateGitInfo = false, standalone, eventTimestamp } = options;
5058

5159
const config = getSpaceConfigOrThrow(spaceInstallation);
5260
assertIsDefined(config.branch, { label: 'config.branch' });
@@ -68,6 +76,7 @@ export async function triggerImport(
6876
repoProjectDirectory: config.projectDirectory,
6977
repoCacheID: config.key,
7078
force,
79+
timestamp: eventTimestamp && !force ? eventTimestamp.toISOString() : undefined,
7180
standalone: !!standalone,
7281
...(updateGitInfo ? { gitInfo: { provider: 'gitlab', url: repoURL } } : {}),
7382
});
@@ -85,10 +94,18 @@ export async function triggerExport(
8594

8695
/** Whether the git info should be updated on the space */
8796
updateGitInfo?: boolean;
97+
98+
/**
99+
* The timestamp of the event that triggers the export.
100+
*
101+
* This is to help ensures that Git sync import and export operations are executed
102+
* in the same order on GitBook and on the remote repository.
103+
*/
104+
eventTimestamp?: Date;
88105
} = {}
89106
) {
90107
const { api } = context;
91-
const { force = false, updateGitInfo = false } = options;
108+
const { force = false, updateGitInfo = false, eventTimestamp } = options;
92109

93110
const config = getSpaceConfigOrThrow(spaceInstallation);
94111
assertIsDefined(config.branch, { label: 'config.branch' });
@@ -112,6 +129,7 @@ export async function triggerExport(
112129
repoProjectDirectory: config.projectDirectory,
113130
repoCacheID: config.key,
114131
force,
132+
timestamp: eventTimestamp && !force ? eventTimestamp.toISOString() : undefined,
115133
commitMessage: getCommitMessageForRevision(config, revision),
116134
...(updateGitInfo ? { gitInfo: { provider: 'gitlab', url: repoURL } } : {}),
117135
});

integrations/gitlab/src/tasks.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export async function handleImportDispatchForSpaces(
5050
context: GitLabRuntimeContext,
5151
payload: IntegrationTaskImportSpaces['payload']
5252
): Promise<number | undefined> {
53-
const { configQuery, page, standaloneRef } = payload;
53+
const { configQuery, page, standaloneRef, eventTimestamp } = payload;
5454

5555
logger.debug(`handling import dispatch for spaces with payload: ${JSON.stringify(payload)}`);
5656

@@ -92,6 +92,7 @@ export async function handleImportDispatchForSpaces(
9292
ref: standaloneRef,
9393
}
9494
: undefined,
95+
eventTimestamp,
9596
});
9697
} catch (error) {
9798
logger.error(

integrations/gitlab/src/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ export type IntegrationTaskImportSpaces = BaseIntegrationTask<
8787
configQuery: string;
8888
page?: string;
8989
standaloneRef?: string;
90+
/**
91+
* The timestamp of the event that triggers the export.
92+
*
93+
* This is to help ensures that Git sync import and export operations are executed
94+
* in the same order on GitBook and on the remote repository.
95+
*/
96+
eventTimestamp?: Date;
9097
}
9198
>;
9299

integrations/gitlab/src/webhooks.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@ import { handleImportDispatchForSpaces } from './tasks';
44
import { GitLabRuntimeContext } from './types';
55
import { computeConfigQueryKey } from './utils';
66

7+
interface GitLabCommit {
8+
id: string;
9+
message: string;
10+
title: string;
11+
timestamp: string;
12+
url: string;
13+
author: {
14+
name: string;
15+
email: string;
16+
};
17+
added: string[];
18+
modified: string[];
19+
removed: string[];
20+
}
21+
722
interface GitLabPushEvent {
823
object_kind: string;
924
before: string;
@@ -18,7 +33,7 @@ interface GitLabPushEvent {
1833
project_id: number;
1934
project: GitLabProject;
2035
repository: any;
21-
commits: any[];
36+
commits: GitLabCommit[];
2237
total_commits_count: number;
2338
}
2439

@@ -88,8 +103,15 @@ export async function handlePushEvent(context: GitLabRuntimeContext, payload: Gi
88103

89104
const queryKey = computeConfigQueryKey(gitlabProjectId, gitlabRef);
90105

106+
// Gitlab push events do not include a head_commit property so we need to get it from
107+
// the commits attribute which should contains the newest 20 commits:
108+
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#push-events
109+
const headCommitSha = payload.after;
110+
const headCommit = payload.commits.find((commit) => commit.id === headCommitSha);
111+
91112
const total = await handleImportDispatchForSpaces(context, {
92113
configQuery: queryKey,
114+
eventTimestamp: headCommit?.timestamp ? new Date(headCommit.timestamp) : undefined,
93115
});
94116

95117
logger.debug(`${total} space configurations are affected`);

0 commit comments

Comments
 (0)