Skip to content

Lifecycle functions rework: structure change, more details & examples #113

Lifecycle functions rework: structure change, more details & examples

Lifecycle functions rework: structure change, more details & examples #113

name: Auto-label PRs by contributor type
on:
pull_request:
types: [opened]
branches: [main, next, v4]
workflow_dispatch:
inputs:
pr_number:
description: 'PR number to label'
required: true
type: string
jobs:
auto-label:
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Read team members configuration
id: team-config
run: |
if [ ! -f ".github/TEAM_MEMBERS.json" ]; then
echo "Error: .github/TEAM_MEMBERS.json file not found"
exit 1
fi
# Read and validate JSON
TEAM_DATA=$(cat .github/TEAM_MEMBERS.json)
echo "team_data<<EOF" >> $GITHUB_OUTPUT
echo "$TEAM_DATA" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Determine contributor type and add label
uses: actions/github-script@v7
with:
script: |
const teamData = JSON.parse(`${{ steps.team-config.outputs.team_data }}`);
// Handle both automatic (PR event) and manual (workflow_dispatch) triggers
let prToProcess;
if (context.eventName === 'pull_request') {
// Automatic trigger: process the current PR
prToProcess = context.payload.pull_request;
} else if (context.eventName === 'workflow_dispatch') {
// Manual trigger: process specified PR
const prNumber = '${{ inputs.pr_number }}';
console.log(`Manual trigger for PR #${prNumber}`);
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: parseInt(prNumber)
});
prToProcess = pr;
}
const prAuthor = prToProcess.user.login;
const prNumber = prToProcess.number;
console.log(`Processing PR #${prNumber} by ${prAuthor}`);
// Check if author is in maintainers or contributors list
const isMaintainer = teamData.maintainers && teamData.maintainers.includes(prAuthor);
const isContributor = teamData.contributors && teamData.contributors.includes(prAuthor);
const isInternal = isMaintainer || isContributor;
console.log(`Is Maintainer: ${isMaintainer}`);
console.log(`Is Contributor: ${isContributor}`);
console.log(`Is Internal: ${isInternal}`);
// Determine the appropriate label
const labelToAdd = isInternal ? 'internal' : 'contribution';
console.log(`Label to add: ${labelToAdd}`);
// Check if the PR already has one of these labels
const existingLabels = prToProcess.labels.map(label => label.name);
const hasInternalLabel = existingLabels.includes('internal');
const hasContributionLabel = existingLabels.includes('contribution');
if (hasInternalLabel || hasContributionLabel) {
console.log(`PR #${prNumber} already has a contributor type label, skipping...`);
return;
}
// Add the label to the PR
try {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: [labelToAdd]
});
console.log(`Successfully added label '${labelToAdd}' to PR #${prNumber}`);
} catch (error) {
console.error(`Error adding label to PR #${prNumber}:`, error);
core.setFailed(`Failed to add label to PR #${prNumber}: ${error.message}`);
}