Skip to content
This repository was archived by the owner on Sep 5, 2025. It is now read-only.

Commit 417d881

Browse files
phernandezclaude
andcommitted
Add organization membership check and PAT support
- Added organization membership verification for issue requests - Added personal access token support for custom commit attribution - Updated documentation with new features - Bumped version to 0.6.0 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent bf86772 commit 417d881

File tree

5 files changed

+134
-18
lines changed

5 files changed

+134
-18
lines changed

README.md

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ on:
3030

3131
jobs:
3232
claude-integration:
33-
uses: fractureinc/claude-code-github-action/.github/workflows/claude-full.yml@v0.5.6
33+
uses: fractureinc/claude-code-github-action/.github/workflows/claude-full.yml@v0.6.0
3434
with:
3535
issue-label: 'claude-fix' # Optional: customize the trigger label
3636
secrets:
@@ -47,7 +47,7 @@ on:
4747
4848
jobs:
4949
claude-label-fix:
50-
uses: fractureinc/claude-code-github-action/.github/workflows/claude-label-fix.yml@v0.5.6
50+
uses: fractureinc/claude-code-github-action/.github/workflows/claude-label-fix.yml@v0.6.0
5151
with:
5252
issue-label: 'claude-fix' # Must match your chosen label
5353
secrets:
@@ -97,30 +97,36 @@ The reusable workflows support several configuration options:
9797
```yaml
9898
jobs:
9999
claude-integration:
100-
uses: fractureinc/claude-code-github-action/.github/workflows/claude-full.yml@v0.5.6
100+
uses: fractureinc/claude-code-github-action/.github/workflows/claude-full.yml@v0.6.0
101101
with:
102102
# All parameters are optional with sensible defaults
103-
issue-label: 'claude-fix' # Label that triggers issue fixes
104-
branch-prefix: 'fix' # Prefix for branches created by fixes
105-
debug-mode: false # Enable verbose logging
106-
strict-mode: true # When false, allows Claude to add improvements
103+
issue-label: 'claude-fix' # Label that triggers issue fixes
104+
branch-prefix: 'fix' # Prefix for branches created by fixes
105+
require-org-membership: true # Only process issues from org members
106+
organization: 'my-org' # Organization to check membership against
107+
debug-mode: false # Enable verbose logging
108+
strict-mode: true # When false, allows Claude to add improvements
107109
secrets:
108110
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
111+
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} # Optional: For commit attribution
109112
```
110113

111114
### Label-Based Integration (`claude-label-fix.yml`)
112115

113116
```yaml
114117
jobs:
115118
claude-label-fix:
116-
uses: fractureinc/claude-code-github-action/.github/workflows/claude-label-fix.yml@v0.5.6
119+
uses: fractureinc/claude-code-github-action/.github/workflows/claude-label-fix.yml@v0.6.0
117120
with:
118121
# All parameters are optional with sensible defaults
119-
issue-label: 'claude-fix' # Must match the label you're using
120-
branch-prefix: 'fix' # Prefix for branches created by fixes
121-
debug-mode: false # Enable verbose logging
122+
issue-label: 'claude-fix' # Must match the label you're using
123+
branch-prefix: 'fix' # Prefix for branches created by fixes
124+
require-org-membership: true # Only process issues from org members
125+
organization: 'my-org' # Organization to check membership against
126+
debug-mode: false # Enable verbose logging
122127
secrets:
123128
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
129+
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} # Optional: For commit attribution
124130
```
125131

126132
Only repo maintainers with write access can add labels, providing security control over which issues Claude will fix.
@@ -145,14 +151,17 @@ When using our reusable workflows, you only need to configure a few key options:
145151
|-----------|-------------|---------|---------|
146152
| `issue-label` | Label that triggers issue fixes | `claude-fix` | Both workflows |
147153
| `branch-prefix` | Prefix for branches created by fixes | `fix` | Both workflows |
154+
| `require-org-membership` | Require the issue creator to be an organization member | `true` | Both workflows |
155+
| `organization` | Organization name to check membership against | Repository owner | Both workflows |
156+
| `personal-access-token` | Token for commits to override the default GitHub token | None | Both workflows |
148157
| `debug-mode` | Enable verbose logging | `false` | Both workflows |
149158
| `strict-mode` | Controls whether Claude adds improvements beyond what's requested | `true` | Comment workflow only |
150159

151160
All parameters are optional and have sensible defaults.
152161

153162
## Enhanced Context for Claude
154163

155-
With version 0.5.6, Claude now receives complete context for your PRs and issues, including:
164+
With version 0.6.0, Claude now receives complete context for your PRs and issues, including:
156165

157166
- PR metadata (title, description, branch info)
158167
- Issue details (title, description, labels)
@@ -211,6 +220,8 @@ permissions:
211220
- Only users with appropriate GitHub permissions can trigger Claude Code actions
212221
- For issue fixes, using the label-based approach gives you more control over who can trigger code changes
213222
- The `strict-mode` parameter limits Claude to only making requested changes
223+
- The `require-org-membership` option ensures only organization members can use Claude for issues
224+
- Using a personal access token for commits ensures proper attribution and bypasses CLA requirements
214225

215226
## License
216227

action.yml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ inputs:
2929
description: 'Label that triggers issue fix workflows'
3030
required: false
3131
default: 'claude-fix'
32+
require-org-membership:
33+
description: 'Whether to require the issue creator to be an organization member to process the issue'
34+
required: false
35+
default: 'true'
36+
organization:
37+
description: 'The GitHub organization name to check membership against (defaults to the repo owner)'
38+
required: false
3239
debug-mode:
3340
description: 'Enable full debug mode with shell tracing and Claude debug output'
3441
required: false
@@ -55,6 +62,9 @@ inputs:
5562
github-token:
5663
description: 'GitHub token for API access'
5764
required: true
65+
personal-access-token:
66+
description: 'Optional personal access token for commits, to override the default GitHub token'
67+
required: false
5868
output-file:
5969
description: 'Path to write the output to (for direct mode)'
6070
required: false
@@ -111,11 +121,11 @@ runs:
111121
shell: bash
112122
run: |
113123
chmod +x ${{ github.action_path }}/scripts/issue-fix-mode.sh
114-
${{ github.action_path }}/scripts/issue-fix-mode.sh "${{ inputs.issue-number }}" "${{ inputs.repo-owner }}" "${{ inputs.repo-name }}" "${{ inputs.branch-prefix }}" "${{ inputs.anthropic-api-key }}" "${{ inputs.github-token }}" "${{ inputs.issue-label }}" "${{ inputs.debug-mode }}" "${{ inputs.feedback }}"
124+
${{ github.action_path }}/scripts/issue-fix-mode.sh "${{ inputs.issue-number }}" "${{ inputs.repo-owner }}" "${{ inputs.repo-name }}" "${{ inputs.branch-prefix }}" "${{ inputs.anthropic-api-key }}" "${{ inputs.github-token }}" "${{ inputs.issue-label }}" "${{ inputs.debug-mode }}" "${{ inputs.feedback }}" "${{ inputs.require-org-membership }}" "${{ inputs.organization }}" "${{ inputs.personal-access-token }}"
115125
116126
- name: Process Issue Analysis
117127
if: inputs.mode == 'issue-analyze'
118128
shell: bash
119129
run: |
120130
chmod +x ${{ github.action_path }}/scripts/issue-analyze-mode.sh
121-
${{ github.action_path }}/scripts/issue-analyze-mode.sh "${{ inputs.issue-number }}" "${{ inputs.repo-owner }}" "${{ inputs.repo-name }}" "${{ inputs.anthropic-api-key }}" "${{ inputs.github-token }}" "${{ inputs.debug-mode }}" "${{ inputs.feedback }}"
131+
${{ github.action_path }}/scripts/issue-analyze-mode.sh "${{ inputs.issue-number }}" "${{ inputs.repo-owner }}" "${{ inputs.repo-name }}" "${{ inputs.anthropic-api-key }}" "${{ inputs.github-token }}" "${{ inputs.debug-mode }}" "${{ inputs.feedback }}" "${{ inputs.require-org-membership }}" "${{ inputs.organization }}"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "claude-code-github-action",
3-
"version": "0.5.6",
3+
"version": "0.6.0",
44
"description": "GitHub action for Claude Code Integration in PR comments, reviews, inline code suggestions, and issue-based fixes",
55
"main": "index.js",
66
"scripts": {

scripts/issue-analyze-mode.sh

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ ANTHROPIC_API_KEY=$4
1010
GITHUB_TOKEN=$5
1111
DEBUG_MODE=${6:-"false"}
1212
FEEDBACK=$7
13+
REQUIRE_ORG_MEMBERSHIP=${8:-"true"}
14+
ORGANIZATION=${9:-$REPO_OWNER}
1315

1416
# Enable debug mode if requested
1517
if [[ "$DEBUG_MODE" == "true" ]]; then
@@ -92,7 +94,7 @@ else
9294
FULL_REPO="$REPO_OWNER/$REPO_NAME"
9395
fi
9496
echo "Using repository: $FULL_REPO"
95-
if ! ISSUE_DETAILS=$(gh issue view $ISSUE_NUMBER --repo "$FULL_REPO" --json title,body,labels); then
97+
if ! ISSUE_DETAILS=$(gh issue view $ISSUE_NUMBER --repo "$FULL_REPO" --json title,body,labels,author); then
9698
echo "Error fetching issue details"
9799
exit 1
98100
fi
@@ -101,6 +103,39 @@ fi
101103
ISSUE_TITLE=$(echo "$ISSUE_DETAILS" | jq -r '.title')
102104
ISSUE_BODY=$(echo "$ISSUE_DETAILS" | jq -r '.body')
103105
ISSUE_LABELS=$(echo "$ISSUE_DETAILS" | jq -r '.labels[].name' | tr '\n' ',' | sed 's/,$//' || echo "none")
106+
ISSUE_AUTHOR=$(echo "$ISSUE_DETAILS" | jq -r '.author.login')
107+
108+
# Check if user is a member of the organization if required
109+
if [[ "$REQUIRE_ORG_MEMBERSHIP" == "true" ]]; then
110+
echo "Checking if $ISSUE_AUTHOR is a member of organization $ORGANIZATION"
111+
ORG_CHECK=$(gh api -X GET /orgs/$ORGANIZATION/members/$ISSUE_AUTHOR --silent -i || true)
112+
STATUS_CODE=$(echo "$ORG_CHECK" | head -n 1 | cut -d' ' -f2)
113+
114+
if [[ "$STATUS_CODE" != "204" ]]; then
115+
echo "User $ISSUE_AUTHOR is not a member of organization $ORGANIZATION. Skipping Claude analysis."
116+
117+
# Leave a comment on the issue explaining why the analysis is skipped
118+
ISSUE_COMMENT=$(cat <<EOF
119+
# Claude Code Analysis Skipped
120+
121+
Sorry, Claude Code can only analyze issues created by organization members.
122+
123+
This is to prevent API usage from users outside the organization.
124+
125+
---
126+
🤖 Generated with Claude Code GitHub Action
127+
EOF
128+
)
129+
130+
echo "Adding comment to issue #$ISSUE_NUMBER explaining why analysis was skipped"
131+
gh issue comment "$ISSUE_NUMBER" --repo "$FULL_REPO" --body "$ISSUE_COMMENT"
132+
133+
echo "Exiting due to non-organization member request"
134+
exit 0
135+
else
136+
echo "User $ISSUE_AUTHOR is a member of organization $ORGANIZATION. Proceeding with Claude analysis."
137+
fi
138+
fi
104139

105140
# Create prompt for Claude
106141
CLAUDE_PROMPT=$(cat <<EOF

scripts/issue-fix-mode.sh

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ GITHUB_TOKEN=$6
1212
ISSUE_LABEL=${7:-"claude-fix"}
1313
DEBUG_MODE=${8:-"false"}
1414
FEEDBACK=$9
15+
REQUIRE_ORG_MEMBERSHIP=${10:-"true"}
16+
ORGANIZATION=${11:-$REPO_OWNER}
17+
PERSONAL_ACCESS_TOKEN=${12:-$GITHUB_TOKEN}
1518

1619
# Enable debug mode if requested
1720
if [[ "$DEBUG_MODE" == "true" ]]; then
@@ -66,10 +69,34 @@ echo "Repo Owner: $REPO_OWNER"
6669
echo "Repo Name: $REPO_NAME"
6770
echo "Branch Prefix: ${BRANCH_PREFIX:-fix}"
6871

69-
# Set up authentication
72+
# Set up authentication for GitHub CLI
7073
echo "$GITHUB_TOKEN" | gh auth login --with-token
7174
export ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY"
7275

76+
# Set up git identity if personal access token is provided
77+
if [[ "$PERSONAL_ACCESS_TOKEN" != "$GITHUB_TOKEN" ]]; then
78+
echo "Using personal access token for git operations"
79+
80+
# Extract user info from the token
81+
USER_INFO=$(curl -s -H "Authorization: token $PERSONAL_ACCESS_TOKEN" https://api.github.com/user)
82+
GIT_USER_NAME=$(echo "$USER_INFO" | jq -r '.name // .login')
83+
GIT_USER_EMAIL=$(echo "$USER_INFO" | jq -r '.email // "\(.login)@users.noreply.github.com"')
84+
85+
# Configure git to use the personal identity
86+
git config --global user.name "$GIT_USER_NAME"
87+
git config --global user.email "$GIT_USER_EMAIL"
88+
89+
# Set credentials for remote push
90+
REPO_URL=$(git config --get remote.origin.url)
91+
# Convert HTTP URLs to use token authentication
92+
if [[ "$REPO_URL" == https://* ]]; then
93+
NEW_REPO_URL="https://x-access-token:$PERSONAL_ACCESS_TOKEN@${REPO_URL#https://}"
94+
git remote set-url origin "$NEW_REPO_URL"
95+
fi
96+
else
97+
echo "Using default GitHub token for git operations"
98+
fi
99+
73100
# Check Claude CLI availability and version
74101
echo "Checking Claude CLI installation..."
75102
which claude || echo "Claude CLI not found in PATH"
@@ -99,7 +126,7 @@ else
99126
FULL_REPO="$REPO_OWNER/$REPO_NAME"
100127
fi
101128
echo "Using repository: $FULL_REPO"
102-
if ! ISSUE_DETAILS=$(gh issue view $ISSUE_NUMBER --repo "$FULL_REPO" --json title,body,labels); then
129+
if ! ISSUE_DETAILS=$(gh issue view $ISSUE_NUMBER --repo "$FULL_REPO" --json title,body,labels,author); then
103130
echo "Error fetching issue details"
104131
exit 1
105132
fi
@@ -108,6 +135,39 @@ fi
108135
ISSUE_TITLE=$(echo "$ISSUE_DETAILS" | jq -r '.title')
109136
ISSUE_BODY=$(echo "$ISSUE_DETAILS" | jq -r '.body')
110137
ISSUE_LABELS=$(echo "$ISSUE_DETAILS" | jq -r '.labels[].name' | tr '\n' ',' | sed 's/,$//' || echo "none")
138+
ISSUE_AUTHOR=$(echo "$ISSUE_DETAILS" | jq -r '.author.login')
139+
140+
# Check if user is a member of the organization if required
141+
if [[ "$REQUIRE_ORG_MEMBERSHIP" == "true" ]]; then
142+
echo "Checking if $ISSUE_AUTHOR is a member of organization $ORGANIZATION"
143+
ORG_CHECK=$(gh api -X GET /orgs/$ORGANIZATION/members/$ISSUE_AUTHOR --silent -i || true)
144+
STATUS_CODE=$(echo "$ORG_CHECK" | head -n 1 | cut -d' ' -f2)
145+
146+
if [[ "$STATUS_CODE" != "204" ]]; then
147+
echo "User $ISSUE_AUTHOR is not a member of organization $ORGANIZATION. Skipping Claude fix."
148+
149+
# Leave a comment on the issue explaining why the fix is skipped
150+
ISSUE_COMMENT=$(cat <<EOF
151+
# Claude Code Fix Skipped
152+
153+
Sorry, Claude Code can only fix issues created by organization members.
154+
155+
This is to prevent API usage from users outside the organization.
156+
157+
---
158+
🤖 Generated with Claude Code GitHub Action
159+
EOF
160+
)
161+
162+
echo "Adding comment to issue #$ISSUE_NUMBER explaining why fix was skipped"
163+
gh issue comment "$ISSUE_NUMBER" --repo "$FULL_REPO" --body "$ISSUE_COMMENT"
164+
165+
echo "Exiting due to non-organization member request"
166+
exit 0
167+
else
168+
echo "User $ISSUE_AUTHOR is a member of organization $ORGANIZATION. Proceeding with Claude fix."
169+
fi
170+
fi
111171

112172
# Get repo info for default branch
113173
REPO_INFO=$(gh repo view "$FULL_REPO" --json name,description,defaultBranchRef)

0 commit comments

Comments
 (0)