-
Notifications
You must be signed in to change notification settings - Fork 17
fix: Get externalid from webhook #177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,31 +21,54 @@ const convertStatus = ( | |
| ): schema.JobStatus => | ||
| status === JobStatus.Completed ? JobStatus.Completed : JobStatus.InProgress; | ||
|
|
||
| const extractUuid = (str: string) => { | ||
| const uuidRegex = | ||
| /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/; | ||
| const match = uuidRegex.exec(str); | ||
| return match ? match[0] : null; | ||
| }; | ||
|
|
||
| const getJob = async (externalId: number, name: string) => { | ||
| const jobFromExternalId = await db | ||
| .select() | ||
| .from(schema.job) | ||
| .where(eq(schema.job.externalId, externalId.toString())) | ||
| .then(takeFirstOrNull); | ||
|
|
||
| if (jobFromExternalId != null) return jobFromExternalId; | ||
|
|
||
| const uuid = extractUuid(name); | ||
| if (uuid == null) return null; | ||
|
|
||
| return db | ||
| .select() | ||
| .from(schema.job) | ||
| .where(eq(schema.job.id, uuid)) | ||
| .then(takeFirstOrNull); | ||
| }; | ||
|
|
||
| export const handleWorkflowWebhookEvent = async (event: WorkflowRunEvent) => { | ||
| const { | ||
| id, | ||
| status: externalStatus, | ||
| conclusion, | ||
| repository, | ||
| name, | ||
| } = event.workflow_run; | ||
|
|
||
| const job = await getJob(id, name); | ||
| if (job == null) return; | ||
|
|
||
| const status = | ||
| conclusion != null | ||
| ? convertConclusion(conclusion) | ||
| : convertStatus(externalStatus); | ||
|
|
||
| const job = await db | ||
| const externalId = id.toString(); | ||
| await db | ||
| .update(schema.job) | ||
| .set({ status }) | ||
| .where(eq(schema.job.externalId, id.toString())) | ||
| .returning() | ||
| .then(takeFirstOrNull); | ||
|
|
||
| // Addressing a race condition: When the job is created externally on GitHub, | ||
| // it triggers a webhook event. However, our system hasn't updated the job with | ||
| // the externalRunId yet, as it depends on the job's instantiation. Therefore, | ||
| // the first event lacks the run ID, so we skip it and wait for the next event. | ||
| if (job == null) return; | ||
| .set({ status, externalId }) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can also generate the url at this point? I think
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we are generating the URL below |
||
| .where(eq(schema.job.id, job.id)); | ||
|
Comment on lines
+67
to
+71
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider using a transaction for atomic updates. The status update and subsequent metadata update should be atomic to prevent potential race conditions. - await db
- .update(schema.job)
- .set({ status, externalId })
- .where(eq(schema.job.id, job.id));
+ await db.transaction(async (tx) => {
+ await tx
+ .update(schema.job)
+ .set({ status, externalId })
+ .where(eq(schema.job.id, job.id));
+
+ const existingUrlMetadata = await tx
+ .select()
+ .from(schema.jobMetadata)
+ // ... rest of the metadata query ...
+
+ // ... metadata update logic ...
+ await tx
+ .insert(schema.jobMetadata)
+ // ... rest of the metadata insert ...
+ });
|
||
|
|
||
| const existingUrlMetadata = await db | ||
| .select() | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling for database operations.
The job retrieval logic is well-structured with a good fallback strategy. However, database operations could throw errors that should be handled gracefully.
const getJob = async (externalId: number, name: string) => { + try { const jobFromExternalId = await db .select() .from(schema.job) .where(eq(schema.job.externalId, externalId.toString())) .then(takeFirstOrNull); if (jobFromExternalId != null) return jobFromExternalId; const uuid = extractUuid(name); if (uuid == null) return null; return db .select() .from(schema.job) .where(eq(schema.job.id, uuid)) .then(takeFirstOrNull); + } catch (error) { + console.error('Failed to retrieve job:', error); + return null; + } };📝 Committable suggestion