Skip to content

Commit dacaabd

Browse files
committed
simplify workflow
1 parent 9be4cd4 commit dacaabd

File tree

1 file changed

+23
-230
lines changed

1 file changed

+23
-230
lines changed

.github/workflows/trademark-cla-approval.yml

Lines changed: 23 additions & 230 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,15 @@
1-
name: CLA Approval Handler
1+
name: CLA Signature Recorder
22

33
on:
4-
workflow_dispatch:
5-
inputs:
6-
pr_number:
7-
description: 'PR number to approve CLA for'
8-
required: true
9-
type: string
104
pull_request_target:
115
types: [labeled]
12-
issue_comment:
13-
types: [created]
146

157
permissions: write-all
168

179
jobs:
18-
process-cla-approval:
10+
record-cla-signature:
1911
runs-on: ubuntu-latest
20-
if: |
21-
(
22-
github.event_name == 'workflow_dispatch' ||
23-
(github.event_name == 'pull_request_target' && github.event.label.name == 'cla-signed') ||
24-
github.event_name == 'issue_comment'
25-
) && github.actor != 'workflow-authentication-public[bot]'
12+
if: github.event.label.name == 'cla-signed' && github.actor != 'workflow-authentication-public[bot]'
2613

2714
steps:
2815

@@ -40,236 +27,42 @@ jobs:
4027
fetch-depth: 0
4128
token: ${{ steps.generate-token.outputs.token || secrets.GITHUB_TOKEN }}
4229

43-
- name: Process CLA approval
44-
id: process-cla-approval
30+
- name: Extract PR Information
31+
id: pr-info
4532
uses: actions/github-script@v7
4633
with:
4734
github-token: ${{ steps.generate-token.outputs.token || secrets.GITHUB_TOKEN }}
4835
script: |
49-
let prNumber;
50-
let approvedBy;
51-
let prAuthor;
52-
let isCommentApproval = false;
36+
// Extract PR details from the event
37+
const prNumber = context.payload.pull_request.number;
38+
const prAuthor = context.payload.pull_request.user.login;
39+
const approvedBy = context.actor;
5340
54-
// Handle different event types
55-
if (context.eventName === 'workflow_dispatch') {
56-
prNumber = parseInt('${{ github.event.inputs.pr_number }}');
57-
approvedBy = context.actor;
58-
} else if (context.eventName === 'pull_request_target') {
59-
prNumber = context.payload.pull_request.number;
60-
approvedBy = context.actor;
61-
} else if (context.eventName === 'issue_comment') {
62-
// Only process comments on pull requests
63-
if (!context.payload.issue.pull_request) {
64-
console.log('Comment is not on a pull request, skipping...');
65-
return;
66-
}
67-
68-
prNumber = context.payload.issue.number;
69-
const commentBody = context.payload.comment.body;
70-
const commenter = context.payload.comment.user.login;
71-
72-
// Check if this is a CLA agreement comment
73-
const isClaAgreement = commentBody.includes('I agree to the Trademark License Addendum') &&
74-
commentBody.includes('CLA-SIGNATURE:');
75-
76-
if (!isClaAgreement) {
77-
console.log('Comment is not a CLA agreement, skipping...');
78-
return;
79-
}
80-
81-
// Extract the signature from the comment
82-
const signatureMatch = commentBody.match(/CLA-SIGNATURE:\s*(\S+)/);
83-
if (!signatureMatch) {
84-
console.log('CLA signature format is invalid');
85-
return;
86-
}
87-
88-
const signatureUser = signatureMatch[1];
89-
90-
// Get PR details to verify the commenter is the PR author
91-
const { data: pr } = await github.rest.pulls.get({
92-
owner: context.repo.owner,
93-
repo: context.repo.repo,
94-
pull_number: prNumber
95-
});
96-
97-
// If someone other than PR author is trying to sign, silently ignore
98-
if (commenter !== pr.user.login) {
99-
console.log(`Comment with CLA text from ${commenter} (not PR author ${pr.user.login}), ignoring silently`);
100-
return;
101-
}
102-
103-
// If PR author is signing but signature doesn't match their username, silently ignore
104-
if (signatureUser !== commenter) {
105-
console.log(`PR author ${commenter} used incorrect signature '${signatureUser}', ignoring silently`);
106-
return;
107-
}
108-
109-
// This is a valid CLA agreement comment from the PR author
110-
approvedBy = commenter; // The PR author approved themselves
111-
prAuthor = commenter;
112-
isCommentApproval = true;
113-
console.log(`Valid CLA agreement from PR author: ${commenter}`);
114-
115-
} else {
116-
console.log('Unknown event type, skipping...');
117-
return;
118-
}
119-
120-
// Get PR details if not already retrieved
121-
if (!prAuthor) {
122-
const { data: pr } = await github.rest.pulls.get({
123-
owner: context.repo.owner,
124-
repo: context.repo.repo,
125-
pull_number: prNumber
126-
});
127-
prAuthor = pr.user.login;
128-
}
129-
130-
// For non-comment approvals, check if the person has the right permissions
131-
console.log(`isCommentApproval: ${isCommentApproval}, context.eventName: ${context.eventName}, context.actor: ${context.actor}`);
132-
if (!isCommentApproval) {
133-
try {
134-
const { data: collaboration } = await github.rest.repos.getCollaboratorPermissionLevel({
135-
owner: context.repo.owner,
136-
repo: context.repo.repo,
137-
username: context.actor
138-
});
139-
140-
// Only admin, maintain, or write permissions can manually approve CLA
141-
const isAuthorized = ['admin', 'maintain', 'write'].includes(collaboration.permission);
142-
143-
if (!isAuthorized) {
144-
// If this was a label event, remove the label
145-
if (context.eventName !== 'workflow_dispatch') {
146-
await github.rest.issues.removeLabel({
147-
owner: context.repo.owner,
148-
repo: context.repo.repo,
149-
issue_number: prNumber,
150-
name: 'cla-signed'
151-
});
152-
}
153-
154-
// Add a comment explaining why the action was blocked
155-
await github.rest.issues.createComment({
156-
owner: context.repo.owner,
157-
repo: context.repo.repo,
158-
issue_number: prNumber,
159-
body: `@${context.actor} Only repository maintainers can manually approve CLAs. ${context.eventName !== 'workflow_dispatch' ? 'The label has been removed.' : ''}`
160-
});
161-
162-
return;
163-
}
164-
} catch (error) {
165-
console.error('Error checking permissions:', error);
166-
return;
167-
}
168-
}
169-
170-
// Check if PR has cla-required label
171-
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
172-
owner: context.repo.owner,
173-
repo: context.repo.repo,
174-
issue_number: prNumber
175-
});
176-
177-
const hasClaRequired = labels.some(label => label.name === 'cla-required');
178-
179-
if (!hasClaRequired) {
180-
console.log('PR does not have cla-required label, skipping...');
181-
return;
182-
}
41+
console.log(`Recording CLA signature for PR #${prNumber}`);
42+
console.log(`PR Author: ${prAuthor}`);
43+
console.log(`Approved by: ${approvedBy}`);
18344
184-
// Remove blocking labels and add cla-signed label
185-
try {
186-
await github.rest.issues.removeLabel({
187-
owner: context.repo.owner,
188-
repo: context.repo.repo,
189-
issue_number: prNumber,
190-
name: 'cla-required'
191-
});
192-
} catch (e) {
193-
// Label not found or already removed
194-
}
195-
196-
try {
197-
await github.rest.issues.removeLabel({
198-
owner: context.repo.owner,
199-
repo: context.repo.repo,
200-
issue_number: prNumber,
201-
name: 'integrations-with-image-change'
202-
});
203-
} catch (e) {
204-
// Label not found or already removed
205-
}
206-
207-
// Add cla-signed label
208-
await github.rest.issues.addLabels({
209-
owner: context.repo.owner,
210-
repo: context.repo.repo,
211-
issue_number: prNumber,
212-
labels: ['cla-signed']
213-
});
214-
215-
// Store the approval information for the next step
45+
// Store the information for the signature recording step
21646
core.setOutput('pr_number', prNumber);
21747
core.setOutput('pr_author', prAuthor);
21848
core.setOutput('approved_by', approvedBy);
219-
220-
console.log(`Outputs set - pr_number: ${prNumber}, pr_author: ${prAuthor}, approved_by: ${approvedBy}`);
221-
222-
// Check if confirmation comment already exists
223-
const comments = await github.rest.issues.listComments({
224-
issue_number: prNumber,
225-
owner: context.repo.owner,
226-
repo: context.repo.repo,
227-
});
228-
229-
const confirmationExists = comments.data.some(comment =>
230-
(comment.user.login === 'github-actions[bot]' || comment.user.type === 'Bot') &&
231-
comment.body.includes('Trademark addendum agreement confirmed ✅')
232-
);
233-
234-
const method = isCommentApproval ? 'Self-signed agreement' :
235-
(context.eventName === 'workflow_dispatch' ? 'Manual approval' : 'Label approval');
236-
237-
if (!confirmationExists) {
238-
await github.rest.issues.createComment({
239-
owner: context.repo.owner,
240-
repo: context.repo.repo,
241-
issue_number: prNumber,
242-
body: `## Trademark license agreement
243-
244-
The trademark license agreement process has been completed for @${prAuthor}.
245-
246-
**Status:** Complete
247-
**Date:** ${new Date().toISOString()}
248-
**Signed by:** @${approvedBy}
249-
**Method:** ${method}
250-
251-
This PR is now unblocked and can proceed with normal review.`
252-
});
253-
}
254-
255-
console.log(`CLA approved for ${prAuthor} by ${approvedBy} via ${method}`)
25649
257-
- name: Record manual CLA approval
258-
if: success() && steps.process-cla-approval.outputs.pr_number != ''
50+
- name: Record CLA Signature
51+
if: success() && steps.pr-info.outputs.pr_number != ''
25952
run: |
26053
set -e # Exit on any error
26154
262-
echo "=== DEBUG: Record manual CLA approval step starting ==="
55+
echo "=== Recording CLA signature ==="
26356
echo "Available outputs:"
264-
echo " pr_number: '${{ steps.process-cla-approval.outputs.pr_number }}'"
265-
echo " pr_author: '${{ steps.process-cla-approval.outputs.pr_author }}'"
266-
echo " approved_by: '${{ steps.process-cla-approval.outputs.approved_by }}'"
57+
echo " pr_number: '${{ steps.pr-info.outputs.pr_number }}'"
58+
echo " pr_author: '${{ steps.pr-info.outputs.pr_author }}'"
59+
echo " approved_by: '${{ steps.pr-info.outputs.approved_by }}'"
26760
268-
# Extract and validate approval details from previous step outputs
269-
USERNAME="${{ steps.process-cla-approval.outputs.pr_author }}"
61+
# Extract signature details
62+
USERNAME="${{ steps.pr-info.outputs.pr_author }}"
27063
DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
271-
PR_NUMBER="${{ steps.process-cla-approval.outputs.pr_number }}"
272-
APPROVED_BY="${{ steps.process-cla-approval.outputs.approved_by }}"
64+
PR_NUMBER="${{ steps.pr-info.outputs.pr_number }}"
65+
APPROVED_BY="${{ steps.pr-info.outputs.approved_by }}"
27366
27467
# Validate required fields
27568
if [ -z "$USERNAME" ] || [ -z "$PR_NUMBER" ] || [ -z "$APPROVED_BY" ]; then

0 commit comments

Comments
 (0)