Skip to content

Commit 4c5cdc9

Browse files
iaminaweclaude
andcommitted
Refactor authorization logic into reusable composite action
This addresses the CodeRabbit refactoring suggestion to eliminate duplicated authorization logic across workflows. Changes: - Created .github/actions/check-org-membership composite action - Extracted 45+ lines of duplicated bash logic into single reusable action - Action accepts trigger-command as input parameter - Both workflows now use the same authorization logic - Reduced maintenance burden and ensured consistency Benefits: - Single source of truth for authorization logic - DRY principle compliance - Future updates apply consistently across all workflows - Easier to test and maintain The composite action: - Checks author_association first (OWNER, MEMBER, COLLABORATOR) - Falls back to organization membership verification - Returns is-authorized boolean output - Supports all event types (issue_comment, pull_request_review, etc.) Addresses: CodeRabbit refactoring suggestion 🤖 Generated with Claude Code Co-Authored-By: Claude <[email protected]>
1 parent 215cc73 commit 4c5cdc9

File tree

3 files changed

+134
-62
lines changed

3 files changed

+134
-62
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
name: Check Organization Membership
2+
description: Checks if a user is authorized via repository permissions or organization membership
3+
4+
inputs:
5+
trigger-command:
6+
description: 'The trigger command to check for (e.g., @claude or /oc-codex)'
7+
required: true
8+
github-token:
9+
description: 'GitHub token with org membership read permissions'
10+
required: true
11+
event-name:
12+
description: 'The GitHub event name (github.event_name)'
13+
required: true
14+
comment-body:
15+
description: 'The comment body if applicable'
16+
required: false
17+
default: ''
18+
comment-author-association:
19+
description: 'The comment author association if applicable'
20+
required: false
21+
default: ''
22+
review-body:
23+
description: 'The review body if applicable'
24+
required: false
25+
default: ''
26+
review-author-association:
27+
description: 'The review author association if applicable'
28+
required: false
29+
default: ''
30+
issue-body:
31+
description: 'The issue body if applicable'
32+
required: false
33+
default: ''
34+
issue-title:
35+
description: 'The issue title if applicable'
36+
required: false
37+
default: ''
38+
issue-author-association:
39+
description: 'The issue author association if applicable'
40+
required: false
41+
default: ''
42+
actor:
43+
description: 'The GitHub actor (github.actor)'
44+
required: true
45+
organization:
46+
description: 'The organization name to check membership in'
47+
required: true
48+
default: 'liatrio-labs'
49+
50+
outputs:
51+
is-authorized:
52+
description: 'Whether the user is authorized to trigger the workflow'
53+
value: ${{ steps.check.outputs.authorized }}
54+
55+
runs:
56+
using: 'composite'
57+
steps:
58+
- name: Check authorization
59+
id: check
60+
shell: bash
61+
env:
62+
GH_TOKEN: ${{ inputs.github-token }}
63+
TRIGGER_COMMAND: ${{ inputs.trigger-command }}
64+
EVENT_NAME: ${{ inputs.event-name }}
65+
COMMENT_BODY: ${{ inputs.comment-body }}
66+
COMMENT_AUTHOR_ASSOC: ${{ inputs.comment-author-association }}
67+
REVIEW_BODY: ${{ inputs.review-body }}
68+
REVIEW_AUTHOR_ASSOC: ${{ inputs.review-author-association }}
69+
ISSUE_BODY: ${{ inputs.issue-body }}
70+
ISSUE_TITLE: ${{ inputs.issue-title }}
71+
ISSUE_AUTHOR_ASSOC: ${{ inputs.issue-author-association }}
72+
ACTOR: ${{ inputs.actor }}
73+
ORGANIZATION: ${{ inputs.organization }}
74+
run: |
75+
# Determine the author association based on event type
76+
if [[ "$EVENT_NAME" == "issue_comment" ]] || [[ "$EVENT_NAME" == "pull_request_review_comment" ]]; then
77+
AUTHOR_ASSOC="$COMMENT_AUTHOR_ASSOC"
78+
elif [[ "$EVENT_NAME" == "pull_request_review" ]]; then
79+
AUTHOR_ASSOC="$REVIEW_AUTHOR_ASSOC"
80+
elif [[ "$EVENT_NAME" == "issues" ]]; then
81+
AUTHOR_ASSOC="$ISSUE_AUTHOR_ASSOC"
82+
fi
83+
84+
# Check if user is a repo collaborator/owner/member first
85+
if [[ "$AUTHOR_ASSOC" == "OWNER" ]] || [[ "$AUTHOR_ASSOC" == "MEMBER" ]] || [[ "$AUTHOR_ASSOC" == "COLLABORATOR" ]]; then
86+
echo "User is authorized via author_association: $AUTHOR_ASSOC"
87+
echo "authorized=true" >> "$GITHUB_OUTPUT"
88+
exit 0
89+
fi
90+
91+
# Check if user is a member of the organization
92+
if gh api "orgs/$ORGANIZATION/members/$ACTOR" --silent 2>/dev/null; then
93+
echo "User is authorized as $ORGANIZATION organization member"
94+
echo "authorized=true" >> "$GITHUB_OUTPUT"
95+
else
96+
echo "User is not authorized"
97+
echo "authorized=false" >> "$GITHUB_OUTPUT"
98+
fi

.github/workflows/claude.yml

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -33,40 +33,27 @@ jobs:
3333
)
3434
)
3535
outputs:
36-
is-authorized: ${{ steps.check.outputs.authorized }}
36+
is-authorized: ${{ steps.check.outputs.is-authorized }}
3737
steps:
38+
- name: Checkout repository
39+
uses: actions/checkout@v4
40+
3841
- name: Check authorization
3942
id: check
40-
env:
41-
GH_TOKEN: ${{ secrets.ORG_MEMBER_CHECK_TOKEN }}
42-
run: |
43-
ACTOR="${{ github.actor }}"
44-
45-
# Check if user is a repo collaborator/owner/member first
46-
if [[ "${{ github.event_name }}" == "issue_comment" ]]; then
47-
AUTHOR_ASSOC="${{ github.event.comment.author_association }}"
48-
elif [[ "${{ github.event_name }}" == "pull_request_review_comment" ]]; then
49-
AUTHOR_ASSOC="${{ github.event.comment.author_association }}"
50-
elif [[ "${{ github.event_name }}" == "pull_request_review" ]]; then
51-
AUTHOR_ASSOC="${{ github.event.review.author_association }}"
52-
elif [[ "${{ github.event_name }}" == "issues" ]]; then
53-
AUTHOR_ASSOC="${{ github.event.issue.author_association }}"
54-
fi
55-
56-
if [[ "$AUTHOR_ASSOC" == "OWNER" ]] || [[ "$AUTHOR_ASSOC" == "MEMBER" ]] || [[ "$AUTHOR_ASSOC" == "COLLABORATOR" ]]; then
57-
echo "User is authorized via author_association: $AUTHOR_ASSOC"
58-
echo "authorized=true" >> "$GITHUB_OUTPUT"
59-
exit 0
60-
fi
61-
62-
# Check if user is a member of liatrio-labs organization
63-
if gh api "orgs/liatrio-labs/members/$ACTOR" --silent 2>/dev/null; then
64-
echo "User is authorized as liatrio-labs organization member"
65-
echo "authorized=true" >> "$GITHUB_OUTPUT"
66-
else
67-
echo "User is not authorized"
68-
echo "authorized=false" >> "$GITHUB_OUTPUT"
69-
fi
43+
uses: ./.github/actions/check-org-membership
44+
with:
45+
trigger-command: '@claude'
46+
github-token: ${{ secrets.ORG_MEMBER_CHECK_TOKEN }}
47+
event-name: ${{ github.event_name }}
48+
comment-body: ${{ github.event.comment.body || '' }}
49+
comment-author-association: ${{ github.event.comment.author_association || '' }}
50+
review-body: ${{ github.event.review.body || '' }}
51+
review-author-association: ${{ github.event.review.author_association || '' }}
52+
issue-body: ${{ github.event.issue.body || '' }}
53+
issue-title: ${{ github.event.issue.title || '' }}
54+
issue-author-association: ${{ github.event.issue.author_association || '' }}
55+
actor: ${{ github.actor }}
56+
organization: 'liatrio-labs'
7057

7158
claude:
7259
needs: check-org-membership

.github/workflows/opencode-gpt-5-codex.yml

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -33,40 +33,27 @@ jobs:
3333
)
3434
)
3535
outputs:
36-
is-authorized: ${{ steps.check.outputs.authorized }}
36+
is-authorized: ${{ steps.check.outputs.is-authorized }}
3737
steps:
38+
- name: Checkout repository
39+
uses: actions/checkout@v4
40+
3841
- name: Check authorization
3942
id: check
40-
env:
41-
GH_TOKEN: ${{ secrets.ORG_MEMBER_CHECK_TOKEN }}
42-
run: |
43-
ACTOR="${{ github.actor }}"
44-
45-
# Check if user is a repo collaborator/owner/member first
46-
if [[ "${{ github.event_name }}" == "issue_comment" ]]; then
47-
AUTHOR_ASSOC="${{ github.event.comment.author_association }}"
48-
elif [[ "${{ github.event_name }}" == "pull_request_review_comment" ]]; then
49-
AUTHOR_ASSOC="${{ github.event.comment.author_association }}"
50-
elif [[ "${{ github.event_name }}" == "pull_request_review" ]]; then
51-
AUTHOR_ASSOC="${{ github.event.review.author_association }}"
52-
elif [[ "${{ github.event_name }}" == "issues" ]]; then
53-
AUTHOR_ASSOC="${{ github.event.issue.author_association }}"
54-
fi
55-
56-
if [[ "$AUTHOR_ASSOC" == "OWNER" ]] || [[ "$AUTHOR_ASSOC" == "MEMBER" ]] || [[ "$AUTHOR_ASSOC" == "COLLABORATOR" ]]; then
57-
echo "User is authorized via author_association: $AUTHOR_ASSOC"
58-
echo "authorized=true" >> "$GITHUB_OUTPUT"
59-
exit 0
60-
fi
61-
62-
# Check if user is a member of liatrio-labs organization
63-
if gh api "orgs/liatrio-labs/members/$ACTOR" --silent 2>/dev/null; then
64-
echo "User is authorized as liatrio-labs organization member"
65-
echo "authorized=true" >> "$GITHUB_OUTPUT"
66-
else
67-
echo "User is not authorized"
68-
echo "authorized=false" >> "$GITHUB_OUTPUT"
69-
fi
43+
uses: ./.github/actions/check-org-membership
44+
with:
45+
trigger-command: '/oc-codex'
46+
github-token: ${{ secrets.ORG_MEMBER_CHECK_TOKEN }}
47+
event-name: ${{ github.event_name }}
48+
comment-body: ${{ github.event.comment.body || '' }}
49+
comment-author-association: ${{ github.event.comment.author_association || '' }}
50+
review-body: ${{ github.event.review.body || '' }}
51+
review-author-association: ${{ github.event.review.author_association || '' }}
52+
issue-body: ${{ github.event.issue.body || '' }}
53+
issue-title: ${{ github.event.issue.title || '' }}
54+
issue-author-association: ${{ github.event.issue.author_association || '' }}
55+
actor: ${{ github.actor }}
56+
organization: 'liatrio-labs'
7057

7158
opencode:
7259
needs: check-org-membership

0 commit comments

Comments
 (0)