From 65e8aff93b76f97e309048a3aac24a6d2ed9748f Mon Sep 17 00:00:00 2001 From: Evan Mattson <35585003+moonbox3@users.noreply.github.com> Date: Fri, 21 Aug 2026 22:37:32 +0000 Subject: [PATCH] Fix DevFlow review command whitespace handling (#7813) --- .github/scripts/review_command.js | 13 +++++++++ .github/tests/test_review_command.js | 37 +++++++++++++++++++++++++ .github/workflows/devflow-pr-review.yml | 28 +++++++++++++++++-- 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 .github/scripts/review_command.js create mode 100644 .github/tests/test_review_command.js diff --git a/.github/scripts/review_command.js b/.github/scripts/review_command.js new file mode 100644 index 000000000..a079274ed --- /dev/null +++ b/.github/scripts/review_command.js @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft. All rights reserved. + +/** + * Check whether a comment contains only the DevFlow review command. + * + * @param {unknown} body - Issue comment body from the GitHub event payload. + * @returns {boolean} Whether the normalized comment is exactly `/review`. + */ +function isReviewCommand(body) { + return typeof body === 'string' && body.trim() === '/review'; +} + +module.exports = isReviewCommand; diff --git a/.github/tests/test_review_command.js b/.github/tests/test_review_command.js new file mode 100644 index 000000000..e9c23beb7 --- /dev/null +++ b/.github/tests/test_review_command.js @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft. All rights reserved. + +/** + * Tests for review_command.js. + * + * Run with: node --test .github/tests/test_review_command.js + */ + +const { describe, it } = require('node:test'); +const assert = require('node:assert/strict'); + +const isReviewCommand = require('../scripts/review_command.js'); + + +describe('review command validation', () => { + it('accepts the exact review command', () => { + assert.equal(isReviewCommand('/review'), true); + }); + + it('accepts surrounding whitespace', () => { + assert.equal(isReviewCommand('/review\r\n'), true); + assert.equal(isReviewCommand(' \n/review\t'), true); + }); + + it('rejects commands with additional content', () => { + assert.equal(isReviewCommand('/reviewer'), false); + assert.equal(isReviewCommand('/review please'), false); + assert.equal(isReviewCommand('/review\nadditional text'), false); + assert.equal(isReviewCommand('/Review'), false); + }); + + it('rejects missing or non-string comment bodies', () => { + assert.equal(isReviewCommand(''), false); + assert.equal(isReviewCommand(null), false); + assert.equal(isReviewCommand(undefined), false); + }); +}); diff --git a/.github/workflows/devflow-pr-review.yml b/.github/workflows/devflow-pr-review.yml index aa886528c..295974f40 100644 --- a/.github/workflows/devflow-pr-review.yml +++ b/.github/workflows/devflow-pr-review.yml @@ -34,18 +34,42 @@ env: MODEL_CONFIG_PATH: ${{ github.workspace }}/devflow/config.ci.yaml jobs: - team_check: + command_check: if: >- github.event_name != 'issue_comment' || ( github.event.issue.pull_request && - github.event.comment.body == '/review' && ( github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER' ) ) runs-on: ubuntu-latest + outputs: + should_review: ${{ steps.check.outputs.should_review }} + steps: + - name: Checkout review command validation + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.base.sha || github.sha }} + sparse-checkout: .github/scripts/review_command.js + fetch-depth: 1 + persist-credentials: false + + - name: Check review command + id: check + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + with: + script: | + const isReviewCommand = require('./.github/scripts/review_command.js'); + const shouldReview = context.eventName !== 'issue_comment' || + isReviewCommand(context.payload.comment?.body); + core.setOutput('should_review', shouldReview ? 'true' : 'false'); + + team_check: + needs: command_check + if: ${{ needs.command_check.outputs.should_review == 'true' }} + runs-on: ubuntu-latest environment: github-app-auth outputs: is_team_member: ${{ steps.check.outputs.is_team_member }}