1
- name : Trademark CLA Approval
1
+ name : CLA Approval Handler
2
2
3
3
on :
4
- issues :
4
+ workflow_dispatch :
5
+ inputs :
6
+ pr_number :
7
+ description : ' PR number to approve CLA for'
8
+ required : true
9
+ type : string
10
+ pull_request :
5
11
types : [labeled]
6
12
7
13
permissions : write-all
8
14
9
15
jobs :
10
16
process-cla-approval :
11
17
runs-on : ubuntu-latest
12
- if : github.event.label.name == 'cla-signed'
18
+ if : github.event_name == 'workflow_dispatch' || github. event.label.name == 'cla-signed'
13
19
14
20
steps :
15
21
- name : Debug - Event info
16
22
run : |
17
23
echo "=== CLA APPROVAL DEBUG ==="
18
24
echo "Event: ${{ github.event_name }}"
19
25
echo "Action: ${{ github.event.action }}"
20
- echo "Label: ${{ github.event.label.name }}"
21
- echo "Added by: ${{ github.actor }}"
22
- echo "Issue number: ${{ github.event.issue.number }}"
23
- echo "Is PR: ${{ github.event.issue.pull_request != null }}"
26
+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
27
+ echo "Manual trigger - PR: ${{ github.event.inputs.pr_number }}"
28
+ else
29
+ echo "Label: ${{ github.event.label.name }}"
30
+ echo "Added by: ${{ github.actor }}"
31
+ echo "PR number: ${{ github.event.number }}"
32
+ fi
24
33
echo "================================="
25
34
26
35
- name : Generate Token
@@ -32,22 +41,30 @@ jobs:
32
41
private-key : " ${{ secrets.WORKFLOW_AUTH_PUBLIC_PRIVATE_KEY }}"
33
42
34
43
- name : Process CLA approval
35
- if : github.event.issue.pull_request != null
36
44
uses : actions/github-script@v7
37
45
with :
38
46
github-token : ${{ steps.generate-token.outputs.token || secrets.GITHUB_TOKEN }}
39
47
script : |
40
48
console.log('=== PROCESSING CLA APPROVAL ===');
49
+ console.log('Event:', context.eventName);
41
50
console.log('Actor:', context.actor);
42
- console.log('PR/Issue number:', context.issue.number);
43
51
44
- // Check if this is actually a PR
45
- if (!context.payload.issue.pull_request) {
46
- console.log('This is not a PR, skipping...');
52
+ let prNumber;
53
+
54
+ // Determine PR number
55
+ if (context.eventName === 'workflow_dispatch') {
56
+ prNumber = parseInt('${{ github.event.inputs.pr_number }}');
57
+ console.log('Manual trigger for PR:', prNumber);
58
+ } else if (context.eventName === 'pull_request') {
59
+ prNumber = context.payload.pull_request.number;
60
+ console.log('Label trigger for PR:', prNumber);
61
+ console.log('Label added:', context.payload.label.name);
62
+ } else {
63
+ console.log('Unexpected event type, skipping...');
47
64
return;
48
65
}
49
66
50
- const prNumber = context.payload.issue.number ;
67
+ console.log('Processing CLA approval for PR:', prNumber) ;
51
68
52
69
// Get PR details
53
70
const { data: pr } = await github.rest.pulls.get({
58
75
59
76
console.log('PR author:', pr.user.login);
60
77
61
- // Check if the person adding the label has the right permissions
78
+ // Check if the person triggering has the right permissions
62
79
try {
63
80
const { data: collaboration } = await github.rest.repos.getCollaboratorPermissionLevel({
64
81
owner: context.repo.owner,
@@ -75,24 +92,53 @@ jobs:
75
92
if (!isAuthorized) {
76
93
console.log('User does not have permission to approve CLA');
77
94
78
- // Remove the label that was added by unauthorized user
79
- await github.rest.issues.removeLabel({
95
+ // If this was a label event, remove the label
96
+ if (context.eventName !== 'workflow_dispatch') {
97
+ await github.rest.issues.removeLabel({
98
+ owner: context.repo.owner,
99
+ repo: context.repo.repo,
100
+ issue_number: prNumber,
101
+ name: 'cla-signed'
102
+ });
103
+ }
104
+
105
+ // Add a comment explaining why the action was blocked
106
+ await github.rest.issues.createComment({
80
107
owner: context.repo.owner,
81
108
repo: context.repo.repo,
82
109
issue_number: prNumber,
83
- name: 'cla-signed'
110
+ body: `@${context.actor} Only repository maintainers can approve CLAs. ${context.eventName !== 'workflow_dispatch' ? 'The label has been removed.' : ''}`
84
111
});
85
112
86
- // Add a comment explaining why the label was removed
87
- await github.rest.issues.createComment({
113
+ console.log('Unauthorized approval attempt blocked');
114
+ return;
115
+ }
116
+
117
+ // Check if PR has cla-required label
118
+ const { data: labels } = await github.rest.issues.listLabelsOnIssue({
119
+ owner: context.repo.owner,
120
+ repo: context.repo.repo,
121
+ issue_number: prNumber
122
+ });
123
+
124
+ const hasClaMeeded = labels.some(label => label.name === 'cla-required');
125
+ console.log('PR has cla-required label:', hasClaMeeded);
126
+
127
+ if (!hasClaMeeded) {
128
+ console.log('PR does not have cla-required label, no action needed');
129
+ return;
130
+ }
131
+
132
+ // Ensure cla-signed label is present
133
+ const hasClaSigned = labels.some(label => label.name === 'cla-signed');
134
+ if (!hasClaSigned) {
135
+ console.log('Adding cla-signed label...');
136
+ await github.rest.issues.addLabels({
88
137
owner: context.repo.owner,
89
138
repo: context.repo.repo,
90
139
issue_number: prNumber,
91
- body: `@${context.actor} Only repository maintainers can approve CLAs by adding the \` cla-signed\` label. The label has been removed.`
140
+ labels: [' cla-signed']
92
141
});
93
-
94
- console.log('Unauthorized approval attempt blocked');
95
- return;
96
142
}
97
143
98
144
// Authorized - proceed with approval
@@ -135,6 +181,7 @@ jobs:
135
181
**Status:** Approved
136
182
**Date:** ${new Date().toISOString()}
137
183
**Approved by:** @${context.actor}
184
+ **Method:** ${context.eventName === 'workflow_dispatch' ? 'Manual approval' : 'Label approval'}
138
185
139
186
This PR is now unblocked and can proceed with normal review!`
140
187
});
0 commit comments