Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions .github/actions/check-org-membership/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: Check Organization Membership
description: Checks if a user is authorized via repository permissions or organization membership

inputs:
trigger-command:
description: 'The trigger command to check for (e.g., @claude or /oc-codex)'
required: true
github-token:
description: 'GitHub token with org membership read permissions'
required: true
event-name:
description: 'The GitHub event name (github.event_name)'
required: true
comment-body:
description: 'The comment body if applicable'
required: false
default: ''
comment-author-association:
description: 'The comment author association if applicable'
required: false
default: ''
review-body:
description: 'The review body if applicable'
required: false
default: ''
review-author-association:
description: 'The review author association if applicable'
required: false
default: ''
issue-body:
description: 'The issue body if applicable'
required: false
default: ''
issue-title:
description: 'The issue title if applicable'
required: false
default: ''
issue-author-association:
description: 'The issue author association if applicable'
required: false
default: ''
actor:
description: 'The GitHub actor (github.actor)'
required: true
organization:
description: 'The organization name to check membership in'
required: true
default: 'liatrio-labs'

outputs:
is-authorized:
description: 'Whether the user is authorized to trigger the workflow'
value: ${{ steps.check.outputs.authorized }}

runs:
using: 'composite'
steps:
- name: Check authorization
id: check
shell: bash
env:
GH_TOKEN: ${{ inputs.github-token }}
TRIGGER_COMMAND: ${{ inputs.trigger-command }}
EVENT_NAME: ${{ inputs.event-name }}
COMMENT_BODY: ${{ inputs.comment-body }}
COMMENT_AUTHOR_ASSOC: ${{ inputs.comment-author-association }}
REVIEW_BODY: ${{ inputs.review-body }}
REVIEW_AUTHOR_ASSOC: ${{ inputs.review-author-association }}
ISSUE_BODY: ${{ inputs.issue-body }}
ISSUE_TITLE: ${{ inputs.issue-title }}
ISSUE_AUTHOR_ASSOC: ${{ inputs.issue-author-association }}
ACTOR: ${{ inputs.actor }}
ORGANIZATION: ${{ inputs.organization }}
run: |
# Determine the author association based on event type
if [[ "$EVENT_NAME" == "issue_comment" ]] || [[ "$EVENT_NAME" == "pull_request_review_comment" ]]; then
AUTHOR_ASSOC="$COMMENT_AUTHOR_ASSOC"
elif [[ "$EVENT_NAME" == "pull_request_review" ]]; then
AUTHOR_ASSOC="$REVIEW_AUTHOR_ASSOC"
elif [[ "$EVENT_NAME" == "issues" ]]; then
AUTHOR_ASSOC="$ISSUE_AUTHOR_ASSOC"
fi
# Check if user is a repo collaborator/owner/member first
if [[ "$AUTHOR_ASSOC" == "OWNER" ]] || [[ "$AUTHOR_ASSOC" == "MEMBER" ]] || [[ "$AUTHOR_ASSOC" == "COLLABORATOR" ]]; then
echo "User is authorized via author_association: $AUTHOR_ASSOC"
echo "authorized=true" >> "$GITHUB_OUTPUT"
exit 0
fi
# Check if user is a member of the organization
if gh api "orgs/$ORGANIZATION/members/$ACTOR" --silent 2>/dev/null; then
echo "User is authorized as $ORGANIZATION organization member"
echo "authorized=true" >> "$GITHUB_OUTPUT"
else
echo "User is not authorized"
echo "authorized=false" >> "$GITHUB_OUTPUT"
fi
50 changes: 37 additions & 13 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,57 @@
types: [submitted]

jobs:
claude:
timeout-minutes: 10
concurrency:
group: claude-${{ github.event_name }}-${{ github.event.issue.number || github.event.pull_request.number || github.run_id }}
cancel-in-progress: true
# Check if the user is a member of liatrio-labs organization
check-org-membership:
runs-on: ubuntu-latest
if: |
(
github.event_name == 'issue_comment' &&
contains(github.event.comment.body, '@claude') &&
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)
contains(github.event.comment.body, '@claude')
) || (
github.event_name == 'pull_request_review_comment' &&
contains(github.event.comment.body, '@claude') &&
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)
contains(github.event.comment.body, '@claude')
) || (
github.event_name == 'pull_request_review' &&
github.event.review.body != null &&
contains(github.event.review.body, '@claude') &&
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.review.author_association)
contains(github.event.review.body, '@claude')
) || (
github.event_name == 'issues' &&
(
(github.event.issue.body != null && contains(github.event.issue.body, '@claude')) ||
contains(github.event.issue.title, '@claude')
) &&
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.issue.author_association)
)
)
outputs:
is-authorized: ${{ steps.check.outputs.is-authorized }}
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Check authorization
id: check
uses: ./.github/actions/check-org-membership
with:
trigger-command: '@claude'
github-token: ${{ secrets.ORG_MEMBER_CHECK_TOKEN }}
event-name: ${{ github.event_name }}
comment-body: ${{ github.event.comment.body || '' }}
comment-author-association: ${{ github.event.comment.author_association || '' }}
review-body: ${{ github.event.review.body || '' }}
review-author-association: ${{ github.event.review.author_association || '' }}
issue-body: ${{ github.event.issue.body || '' }}
issue-title: ${{ github.event.issue.title || '' }}
issue-author-association: ${{ github.event.issue.author_association || '' }}
actor: ${{ github.actor }}
organization: 'liatrio-labs'

claude:
needs: check-org-membership
if: needs.check-org-membership.outputs.is-authorized == 'true'
timeout-minutes: 10
concurrency:
group: claude-${{ github.event_name }}-${{ github.event.issue.number || github.event.pull_request.number || github.run_id }}
cancel-in-progress: true
runs-on: ubuntu-latest
permissions:
contents: read
Expand Down
50 changes: 37 additions & 13 deletions .github/workflows/opencode-gpt-5-codex.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,57 @@
types: [submitted]

jobs:
opencode:
timeout-minutes: 30 # to accommodate Codex's ability to run for extended periods
concurrency:
group: opencode-${{ github.event_name }}-${{ github.event.issue.number || github.event.pull_request.number || github.run_id }}
cancel-in-progress: true
# Check if the user is a member of liatrio-labs organization
check-org-membership:
runs-on: ubuntu-latest
if: |
(
github.event_name == 'issue_comment' &&
contains(github.event.comment.body, '/oc-codex') &&
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)
contains(github.event.comment.body, '/oc-codex')
) || (
github.event_name == 'pull_request_review_comment' &&
contains(github.event.comment.body, '/oc-codex') &&
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)
contains(github.event.comment.body, '/oc-codex')
) || (
github.event_name == 'pull_request_review' &&
github.event.review.body != null &&
contains(github.event.review.body, '/oc-codex') &&
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.review.author_association)
contains(github.event.review.body, '/oc-codex')
) || (
github.event_name == 'issues' &&
(
(github.event.issue.body != null && contains(github.event.issue.body, '/oc-codex')) ||
contains(github.event.issue.title, '/oc-codex')
) &&
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.issue.author_association)
)
)
outputs:
is-authorized: ${{ steps.check.outputs.is-authorized }}
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Check authorization
id: check
uses: ./.github/actions/check-org-membership
with:
trigger-command: '/oc-codex'
github-token: ${{ secrets.ORG_MEMBER_CHECK_TOKEN }}
event-name: ${{ github.event_name }}
comment-body: ${{ github.event.comment.body || '' }}
comment-author-association: ${{ github.event.comment.author_association || '' }}
review-body: ${{ github.event.review.body || '' }}
review-author-association: ${{ github.event.review.author_association || '' }}
issue-body: ${{ github.event.issue.body || '' }}
issue-title: ${{ github.event.issue.title || '' }}
issue-author-association: ${{ github.event.issue.author_association || '' }}
actor: ${{ github.actor }}
organization: 'liatrio-labs'

opencode:
needs: check-org-membership
if: needs.check-org-membership.outputs.is-authorized == 'true'
timeout-minutes: 30 # to accommodate Codex's ability to run for extended periods
concurrency:
group: opencode-${{ github.event_name }}-${{ github.event.issue.number || github.event.pull_request.number || github.run_id }}
cancel-in-progress: true
runs-on: ubuntu-latest
permissions:
contents: read
Expand Down