Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
80 changes: 80 additions & 0 deletions .github/actions/check-external-contributor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Check External Contributor Action

Automatically labels pull requests created by users who are not members of a specified GitHub team.

## Usage

```yaml
- uses: SolaceDev/solace-public-workflows/check-external-contributor@main
with:
github_team_slug: solace-ai
label_name: "external contributor"
github-token: ${{ secrets.GITHUB_TOKEN }}
```

## Inputs

| Input | Description | Required | Default |
|-------|-------------|----------|---------|
| `github_team_slug` | GitHub team slug to check membership against (e.g., `solace-ai`) | Yes | - |
| `label_name` | Label to add to PR if creator is not in the team | No | `"external contributor"` |
| `github-token` | GitHub token for API access | Yes | - |

## How it Works

1. Checks if the PR creator is a member of the specified GitHub team
2. If not a member, adds the specified label to the PR
3. Logs the results for debugging

## Workflow Trigger

This action is designed to work with `pull_request_target` to safely handle external contributors:

```yaml
on:
pull_request_target:
types: [opened, reopened]

jobs:
check-external:
runs-on: ubuntu-latest
permissions:
pull-requests: write
issues: write
```

## Examples

### Basic Example

```yaml
name: Check External Contributor
on:
pull_request_target:
types: [opened, reopened]

jobs:
check:
runs-on: ubuntu-latest
permissions:
pull-requests: write
issues: write
steps:
- uses: SolaceDev/solace-public-workflows/check-external-contributor@main
with:
github_team_slug: my-team
label_name: "external contributor"
github-token: ${{ secrets.GITHUB_TOKEN }}
```

## Permissions Required

The GitHub token must have the following permissions:
- `pull-requests: write` - To access PR information
- `issues: write` - To add labels to PRs

## Notes

- Use `pull_request_target` instead of `pull_request` for security when running workflows on external PRs
- The action gracefully handles errors when checking team membership
- If the label doesn't exist, GitHub will automatically create it when adding it to the PR
71 changes: 71 additions & 0 deletions .github/actions/check-external-contributor/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Check External Contributor
description: Checks if PR creator is in a GitHub team and adds a label if not

inputs:
github_team_slug:
description: "GitHub team slug to check membership against (e.g., 'solace-ai')"
required: true
label_name:
description: "Label to add to PR if creator is not in the team"
required: false
default: "external contributor"
github-token:
description: "GitHub token for API access"
required: true

runs:
using: composite
steps:
- name: Check if PR creator is in team
id: check-team
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ inputs.github-token }}
script: |
const teamSlug = '${{ inputs.github_team_slug }}';
const org = context.repo.owner;
const prCreator = context.payload.pull_request.user.login;

console.log(`🔍 Checking team membership for PR creator...`);
console.log(` - Team slug: ${teamSlug}`);
console.log(` - PR creator: ${prCreator}`);
console.log(` - Organization: ${org}`);

try {
const { data } = await github.rest.teams.getMembershipForUserInOrg({
org: org,
team_slug: teamSlug,
username: prCreator
});

core.setOutput('is_member', 'true');
console.log(`✅ PR creator is a member of the team`);
} catch (error) {
if (error.status === 404) {
core.setOutput('is_member', 'false');
console.log(`⚠️ PR creator is not a member of the team`);
} else {
console.log(`⚠️ Could not verify team membership (${error.message}), assuming external contributor`);
core.setOutput('is_member', 'false');
}
Comment on lines +44 to +50
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@johnvincentcorpuz when running this with pull_request_target and testing with a PR using my internal solace-mdupls github account which is part of the solace-ai team, I get a 404 and the resulting "PR creator is not a member of the team". Does the github token I use as part of this workflow have the necessary permissions to read team membership?

Note that I have tried @clarkbains suggestion here to use pull_request_target instead of pull_request, but I cannot seem to trigger the workflow on PRs from external contributors (in this case my personal Github): SolaceLabs/solace-agent-mesh#1120

See thread with Clark: https://solacedotcom.slack.com/archives/C084S3XTD8S/p1772498735212189?thread_ts=1772496075.926289&cid=C084S3XTD8S and used

}

- name: Add external contributor label
if: steps.check-team.outputs.is_member == 'false'
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ inputs.github-token }}
script: |
const labelName = '${{ inputs.label_name }}';
const prNumber = context.issue.number;

console.log(`🏷️ Adding label "${labelName}" to PR #${prNumber}...`);

await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: [labelName]
});

console.log(`✅ Added label "${labelName}" to PR #${prNumber}`);