Python: Add Mistral chat client #1626
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: DevFlow PR Review | |
| on: | |
| pull_request_target: | |
| types: | |
| - opened | |
| - reopened | |
| - ready_for_review | |
| issue_comment: | |
| types: | |
| - created | |
| workflow_dispatch: | |
| inputs: | |
| pr_number: | |
| description: Pull request number to review | |
| required: true | |
| type: string | |
| permissions: | |
| contents: read | |
| id-token: write | |
| issues: write | |
| pull-requests: write | |
| concurrency: | |
| group: devflow-pr-review-${{ github.repository }}-${{ github.event.pull_request.number || github.event.issue.number || inputs.pr_number || github.run_id }} | |
| cancel-in-progress: true | |
| env: | |
| DEVFLOW_REPOSITORY: ${{ vars.DF_REPO }} | |
| DEVFLOW_REF: main | |
| TARGET_REPO_PATH: ${{ github.workspace }}/target-repo | |
| DEVFLOW_PATH: ${{ github.workspace }}/devflow | |
| MODEL_CONFIG_PATH: ${{ github.workspace }}/devflow/config.ci.yaml | |
| jobs: | |
| team_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 | |
| environment: github-app-auth | |
| outputs: | |
| is_team_member: ${{ steps.check.outputs.is_team_member }} | |
| pr_number: ${{ steps.pr.outputs.pr_number }} | |
| pr_url: ${{ steps.pr.outputs.pr_url }} | |
| repo: ${{ steps.pr.outputs.repo }} | |
| steps: | |
| - name: Resolve PR metadata | |
| id: pr | |
| shell: bash | |
| env: | |
| PR_HTML_URL: ${{ github.event.pull_request.html_url }} | |
| PR_NUMBER_COMMENT: ${{ github.event.issue.number }} | |
| PR_NUMBER_EVENT: ${{ github.event.pull_request.number }} | |
| PR_NUMBER_INPUT: ${{ inputs.pr_number }} | |
| run: | | |
| set -euo pipefail | |
| if [[ "${GITHUB_EVENT_NAME}" == "pull_request_target" ]]; then | |
| pr_number="${PR_NUMBER_EVENT}" | |
| pr_url="${PR_HTML_URL}" | |
| elif [[ "${GITHUB_EVENT_NAME}" == "issue_comment" ]]; then | |
| pr_number="${PR_NUMBER_COMMENT}" | |
| pr_url="https://github.com/${GITHUB_REPOSITORY}/pull/${pr_number}" | |
| else | |
| pr_number="${PR_NUMBER_INPUT}" | |
| pr_url="https://github.com/${GITHUB_REPOSITORY}/pull/${pr_number}" | |
| fi | |
| if [[ ! "$pr_number" =~ ^[1-9][0-9]*$ ]]; then | |
| echo "Could not determine PR number; for workflow_dispatch runs, the 'pr_number' input is required when not running on pull_request_target." >&2 | |
| exit 1 | |
| fi | |
| echo "pr_url=${pr_url}" >> "$GITHUB_OUTPUT" | |
| echo "pr_number=${pr_number}" >> "$GITHUB_OUTPUT" | |
| echo "repo=${GITHUB_REPOSITORY}" >> "$GITHUB_OUTPUT" | |
| - name: Checkout GitHub automation | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.base.sha || github.sha }} | |
| sparse-checkout: | | |
| .github/actions/github-app-token | |
| .github/scripts/check_team_membership.js | |
| fetch-depth: 1 | |
| persist-credentials: false | |
| - name: Get GitHub automation token | |
| id: github-auth | |
| uses: ./.github/actions/github-app-token | |
| with: | |
| mode: ${{ vars.GH_APP_AUTH_MODE }} | |
| azure-client-id: ${{ secrets.GH_APP_AZURE_CLIENT_ID }} | |
| azure-tenant-id: ${{ secrets.GH_APP_AZURE_TENANT_ID }} | |
| azure-subscription-id: ${{ secrets.GH_APP_AZURE_SUBSCRIPTION_ID }} | |
| key-vault-name: ${{ secrets.GH_APP_KEY_VAULT_NAME }} | |
| key-name: ${{ secrets.GH_APP_KEY_NAME }} | |
| github-app-client-id: ${{ secrets.GH_APP_CLIENT_ID }} | |
| github-app-installation-id: ${{ secrets.GH_APP_INSTALLATION_ID }} | |
| repository: ${{ github.repository }} | |
| fallback-token: ${{ secrets.GH_ACTIONS_PR_WRITE }} | |
| - name: Check review requester team membership | |
| id: check | |
| uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 | |
| env: | |
| MEMBERSHIP_USER: ${{ github.event_name == 'issue_comment' && github.event.comment.user.login || '' }} | |
| TEAM_NAME: ${{ secrets.DEVELOPER_TEAM }} | |
| PR_NUMBER: ${{ steps.pr.outputs.pr_number }} | |
| with: | |
| github-token: ${{ steps.github-auth.outputs.token }} | |
| script: | | |
| const checkTeamMembership = require('./.github/scripts/check_team_membership.js'); | |
| const { author, isTeamMember } = await checkTeamMembership({ | |
| github, | |
| context, | |
| core, | |
| teamSlug: process.env.TEAM_NAME, | |
| issueNumber: process.env.PR_NUMBER, | |
| username: process.env.MEMBERSHIP_USER, | |
| }); | |
| core.setOutput('is_team_member', isTeamMember ? 'true' : 'false'); | |
| if (isTeamMember) { | |
| core.info(`User ${author} is a team member; proceeding with review.`); | |
| } else { | |
| core.info(`User ${author} is not a member of ${process.env.TEAM_NAME}; skipping review.`); | |
| } | |
| - name: React to authorized review command | |
| if: ${{ github.event_name == 'issue_comment' && steps.check.outputs.is_team_member == 'true' }} | |
| uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 | |
| with: | |
| github-token: ${{ steps.github-auth.outputs.token }} | |
| script: | | |
| await github.rest.reactions.createForIssueComment({ | |
| ...context.repo, | |
| comment_id: context.payload.comment.id, | |
| content: 'eyes', | |
| }); | |
| review: | |
| runs-on: ubuntu-latest | |
| needs: team_check | |
| if: ${{ needs.team_check.outputs.is_team_member == 'true' }} | |
| permissions: | |
| copilot-requests: write | |
| contents: read | |
| issues: write | |
| pull-requests: write | |
| timeout-minutes: 60 | |
| # Advisory check: failures here should not block the PR. The reviewer | |
| # posts comments as a best-effort signal; if the pipeline breaks, the | |
| # PR author should still be able to merge without a red required check. | |
| continue-on-error: true | |
| steps: | |
| # Safe checkout: base repo only, not the untrusted PR head. | |
| - name: Checkout target repo base | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.base.sha || github.sha }} | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| path: target-repo | |
| # Private DevFlow checkout: the PAT/token grants access to this repo's code. | |
| - name: Checkout DevFlow | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| repository: ${{ env.DEVFLOW_REPOSITORY }} | |
| ref: ${{ env.DEVFLOW_REF }} | |
| token: ${{ secrets.DEVFLOW_TOKEN }} | |
| fetch-depth: 1 | |
| persist-credentials: false | |
| path: devflow | |
| - name: Set up Python | |
| uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 | |
| with: | |
| python-version: "3.13" | |
| - name: Set up uv | |
| uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 | |
| with: | |
| version: "0.11.x" | |
| enable-cache: true | |
| - name: Install DevFlow dependencies | |
| working-directory: ${{ env.DEVFLOW_PATH }} | |
| run: uv sync --frozen | |
| - name: Run PR review | |
| id: review | |
| working-directory: ${{ env.DEVFLOW_PATH }} | |
| env: | |
| DEVFLOW_TOKEN: ${{ secrets.DEVFLOW_TOKEN }} | |
| GITHUB_TOKEN: ${{ github.token }} | |
| SK_REPO_PATH: ${{ env.TARGET_REPO_PATH }} | |
| AGENT_REPO_PATH: ${{ env.TARGET_REPO_PATH }} | |
| PR_URL: ${{ needs.team_check.outputs.pr_url }} | |
| run: | | |
| uv run python scripts/trigger_pr_review.py \ | |
| --pr-url "$PR_URL" \ | |
| --github-username "$GITHUB_ACTOR" \ | |
| --review-compare \ | |
| --no-require-comment-selection |