From 49e392423a58ceaf2128156e6f0b8dd9e1f37ba5 Mon Sep 17 00:00:00 2001 From: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com> Date: Sat, 10 Jan 2026 16:17:18 +0530 Subject: [PATCH] feat: reuse PR-creator Devin session when addressing Cubic AI reviews (#26683) * feat: prioritize PR-creator Devin session when addressing Cubic AI reviews Co-Authored-By: anik@cal.com * fix: always use PR-creator Devin session regardless of status Co-Authored-By: anik@cal.com * fix: use checkSessionStatus helper for both PR description and comment cases Co-Authored-By: anik@cal.com * Clarify comment about PR review session check --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .github/workflows/cubic-devin-review.yml | 49 ++++++++++++++++++------ 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/.github/workflows/cubic-devin-review.yml b/.github/workflows/cubic-devin-review.yml index 015984f58a..d8b0fc6678 100644 --- a/.github/workflows/cubic-devin-review.yml +++ b/.github/workflows/cubic-devin-review.yml @@ -46,7 +46,7 @@ jobs: core.setOutput('has-prompt', 'true'); - - name: Check for existing Devin session from PR comments + - name: Check for existing Devin session if: steps.extract-prompt.outputs.has-prompt == 'true' id: check-session uses: actions/github-script@v7 @@ -54,6 +54,41 @@ jobs: DEVIN_API_KEY: ${{ secrets.DEVIN_API_KEY }} with: script: | + async function checkSessionStatus(sessionId) { + const response = await fetch(`https://api.devin.ai/v1/sessions/${sessionId}`, { + headers: { + 'Authorization': `Bearer ${process.env.DEVIN_API_KEY}`, + 'Content-Type': 'application/json' + } + }); + + if (!response.ok) { + console.log(`Failed to fetch session ${sessionId}: ${response.status}`); + return null; + } + + return await response.json(); + } + + // If PR was created through Devin, always use that session + const prBody = context.payload.pull_request.body || ''; + const prSessionMatch = prBody.match(/app\.devin\.ai\/sessions\/([a-f0-9-]+)/); + + if (prSessionMatch) { + const sessionId = prSessionMatch[1]; + console.log(`PR was created by Devin session: ${sessionId}`); + + const session = await checkSessionStatus(sessionId); + if (session) { + console.log(`PR creator session status: ${session.status_enum}`); + core.exportVariable('EXISTING_SESSION_ID', sessionId); + core.exportVariable('SESSION_URL', `https://app.devin.ai/sessions/${sessionId}`); + core.setOutput('has-active-session', 'true'); + return; + } + } + + // PR was not created through Devin - check for existing Devin session from PR comments const comments = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, @@ -79,20 +114,12 @@ jobs: console.log(`Found session ID from comment: ${sessionId}`); - const response = await fetch(`https://api.devin.ai/v1/sessions/${sessionId}`, { - headers: { - 'Authorization': `Bearer ${process.env.DEVIN_API_KEY}`, - 'Content-Type': 'application/json' - } - }); - - if (!response.ok) { - console.log(`Failed to fetch session details: ${response.status}`); + const session = await checkSessionStatus(sessionId); + if (!session) { core.setOutput('has-active-session', 'false'); return; } - const session = await response.json(); const activeStatuses = ['working', 'blocked', 'resumed']; if (activeStatuses.includes(session.status_enum)) {