microsoft/teams.net

Public

mirrored fromhttps://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
3ddf9fa76ec1801a0e3ca312c6d9855879571ac1

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

.github/workflows/copilot-attestation-check.yml

99lines · modecode

1name: Copilot PR Attestation Check
2
3on:
4 pull_request:
5 branches: ['main']
6 types: [opened, synchronize, reopened]
7 issue_comment:
8 types: [created, edited]
9 pull_request_review_comment:
10 types: [created, edited]
11
12permissions:
13 pull-requests: write
14 issues: write
15 contents: read
16
17jobs:
18 check-attestation:
19 name: Check Copilot Attestation
20 runs-on: ubuntu-latest
21 if: |
22 (github.event_name == 'pull_request' && github.event.pull_request.user.login == 'Copilot') ||
23 (github.event_name == 'issue_comment' && contains(github.event.comment.html_url, '/pull/')) ||
24 (github.event_name == 'pull_request_review_comment')
25 steps:
26 - name: Check for attestation comment
27 uses: actions/github-script@v7
28 with:
29 script: |
30 // Handle both pull_request and issue_comment events
31 const prNumber = context.payload.pull_request?.number || context.payload.issue?.number;
32
33 // For issue_comment events, we need to fetch the PR details
34 let pullRequest;
35 if (context.payload.pull_request) {
36 pullRequest = context.payload.pull_request;
37 } else {
38 const pr = await github.rest.pulls.get({
39 owner: context.repo.owner,
40 repo: context.repo.repo,
41 pull_number: prNumber
42 });
43 pullRequest = pr.data;
44 }
45
46 const prCreator = pullRequest.user.login;
47
48 // Skip if not a Copilot PR
49 if (prCreator !== 'Copilot') {
50 console.log(`Skipping - PR not created by Copilot (creator: ${prCreator})`);
51 return;
52 }
53
54 console.log(`PR #${prNumber} created by: ${prCreator}`);
55 console.log(`Event triggered by: ${context.payload.sender.login}`);
56
57 // Get all assignees excluding Copilot (these should be human requestors)
58 const assignees = pullRequest.assignees || [];
59 const humanAssignees = assignees
60 .filter(a => a.login !== prCreator)
61 .map(a => a.login);
62
63 console.log(`Human assignees (potential requestors): ${humanAssignees.join(', ')}`);
64
65 // Get all comments on the PR
66 const comments = await github.rest.issues.listComments({
67 owner: context.repo.owner,
68 repo: context.repo.repo,
69 issue_number: prNumber
70 });
71
72 console.log(`Found ${comments.data.length} comments`);
73
74 // Check if any comment from human assignees contains attestation
75 const attestationPhrases = [
76 'I attest that I have verified',
77 'I attest that no verification is required'
78 ];
79
80 const attestations = comments.data.filter(comment => {
81 const isFromHumanAssignee = humanAssignees.includes(comment.user.login);
82 const containsAttestation = attestationPhrases.some(phrase =>
83 comment.body.includes(phrase)
84 );
85
86 if (isFromHumanAssignee && containsAttestation) {
87 console.log(`✓ Found attestation in comment #${comment.id} from ${comment.user.login}`);
88 console.log(`Comment: ${comment.body.substring(0, 100)}...`);
89 }
90
91 return isFromHumanAssignee && containsAttestation;
92 });
93
94 if (attestations.length > 0) {
95 console.log(`✓ Attestation found from: ${attestations.map(a => a.user.login).join(', ')}`);
96 } else {
97 console.log(`✗ No attestation found from any human assignee`);
98 core.setFailed(`At least one human assignee (${humanAssignees.join(', ')}) must attest with either "I attest that I have verified" or "I attest that no verification is required"`);
99 }
100