Skip to content

try using another api for checking #116

try using another api for checking

try using another api for checking #116

Workflow file for this run

name: Sync PR Labels
on:
pull_request:
types: [opened, reopened, synchronize, edited]
pull_request_target:
types: [opened, reopened, synchronize, edited]
permissions:
contents: read
pull-requests: write
issues: write
jobs:
sync-labels:
if: ${{ github.repository_owner == 'AOSSIE-Org' }}
runs-on: ubuntu-latest
steps:
- name: Get PR details
id: pr-details
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const pr = context.payload.pull_request;
return {
number: pr.number,
body: pr.body || '',
base: pr.base.ref,
head: pr.head.ref
};
# STEP 1: Issue-based labels
- name: Extract linked issue number
id: extract-issue
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const prBody = context.payload.pull_request.body || '';
// Match patterns: Fixes #123, Closes #123, Resolves #123, etc.
const issuePatterns = [
/(?:fix|fixes|fixed|close|closes|closed|resolve|resolves|resolved)\s+#(\d+)/gi,
/#(\d+)/g
];
let issueNumber = null;
for (const pattern of issuePatterns) {
const match = prBody.match(pattern);
if (match) {
const numbers = match.map(m => m.match(/\d+/)[0]);
issueNumber = numbers[0];
break;
}
}
core.setOutput('issue_number', issueNumber || '');
return issueNumber;
- name: Apply issue-based labels
if: steps.extract-issue.outputs.issue_number != ''
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const issueNumber = '${{ steps.extract-issue.outputs.issue_number }}';
const prNumber = context.payload.pull_request.number;
try {
// Fetch issue labels
const issue = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: parseInt(issueNumber)
});
const issueLabels = issue.data.labels.map(label =>
typeof label === 'string' ? label : label.name
);
if (issueLabels.length > 0) {
console.log(`Applying issue-based labels: ${issueLabels.join(', ')}`);
// Add labels from issue
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: issueLabels
});
}
} catch (error) {
console.log(`Error fetching issue #${issueNumber}: ${error.message}`);
}
- name: Mark no issue linked
if: steps.extract-issue.outputs.issue_number == ''
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const prNumber = context.payload.pull_request.number;
console.log('No issue linked to this PR');
// Add "no-issue-linked" label
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: ['no-issue-linked']
});
# STEP 2: File-based labels
- name: Get changed files
id: changed-files
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const prNumber = context.payload.pull_request.number;
// Get list of files changed in the PR
const files = await github.rest.pulls.listFiles({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
const changedFiles = files.data.map(file => file.filename);
core.setOutput('files', JSON.stringify(changedFiles));
return changedFiles;
- name: Apply file-based labels
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const prNumber = context.payload.pull_request.number;
const changedFiles = JSON.parse('${{ steps.changed-files.outputs.files }}');
const fileLabels = [];
// Define file-based label mappings
const labelMappings = {
'documentation': ['.md', 'README', 'CONTRIBUTING', 'LICENSE', '.txt'],
'frontend': ['.html', '.css', '.scss', '.jsx', '.tsx', '.vue'],
'backend': ['.py', '.java', '.go', '.rb', '.php', '.rs'],
'javascript': ['.js', '.ts', '.jsx', '.tsx'],
'python': ['.py'],
'configuration': ['.yml', '.yaml', '.json', '.toml', '.ini', '.env', '.config'],
'github-actions': ['.github/workflows/'],
'dependencies': ['package.json', 'requirements.txt', 'Gemfile', 'Cargo.toml', 'go.mod', 'pom.xml'],
'tests': ['test/', '__tests__/', '.test.', '.spec.', '_test.'],
'docker': ['Dockerfile', 'docker-compose', '.dockerignore'],
'ci-cd': ['.github/', '.gitlab-ci', 'Jenkinsfile', '.circleci']
};
// Check each file against label mappings
for (const file of changedFiles) {
for (const [label, patterns] of Object.entries(labelMappings)) {
for (const pattern of patterns) {
if (file.includes(pattern) || file.endsWith(pattern)) {
if (!fileLabels.includes(label)) {
fileLabels.push(label);
}
}
}
}
}
if (fileLabels.length > 0) {
console.log(`Applying file-based labels: ${fileLabels.join(', ')}`);
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: fileLabels
});
} else {
console.log('No file-based labels matched');
}
# STEP 3: PR size labels
- name: Apply PR size label
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const prNumber = context.payload.pull_request.number;
// Get PR details to calculate size
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
const additions = pr.data.additions;
const deletions = pr.data.deletions;
const totalChanges = additions + deletions;
console.log(`PR has ${additions} additions and ${deletions} deletions (${totalChanges} total changes)`);
// Determine size label based on total changes
let sizeLabel = '';
if (totalChanges <= 10) {
sizeLabel = 'size/XS';
} else if (totalChanges <= 50) {
sizeLabel = 'size/S';
} else if (totalChanges <= 200) {
sizeLabel = 'size/M';
} else if (totalChanges <= 500) {
sizeLabel = 'size/L';
} else {
sizeLabel = 'size/XL';
}
console.log(`Applying size label: ${sizeLabel}`);
// Remove any existing size labels first
const currentLabels = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber
});
const sizeLabelsToRemove = currentLabels.data
.map(label => label.name)
.filter(name => name.startsWith('size/'));
for (const label of sizeLabelsToRemove) {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
name: label
});
}
// Apply the new size label
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: [sizeLabel]
});
# STEP 4: Contributor-based labels
- name: Apply contributor-based labels
uses: actions/github-script@v7
env:
LABELLER_TOKEN: ${{ secrets.EXTERNAL_LABELLER_TOKEN || secrets.GITHUB_TOKEN }}
with:
github-token: ${{ env.LABELLER_TOKEN }}
script: |
const prNumber = context.payload.pull_request.number;
const prAuthor = context.payload.pull_request.user.login;
try {
// Check if user is a first-time contributor
const commits = await github.rest.repos.listCommits({
owner: context.repo.owner,
repo: context.repo.repo,
author: prAuthor
});
const contributorLabels = [];
// Determine contributor type based on commit count
if (commits.data.length <= 1) {
contributorLabels.push('first-time-contributor');
} else {
contributorLabels.push('external-contributor');
}
// Maintainer check
try {
const permissionLevel = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: prAuthor
});
if (['admin', 'maintain'].includes(permissionLevel.data.permission)) {
contributorLabels.push('maintainer');
}
} catch (error) {
console.log('Could not check collaborator status');
}
if (contributorLabels.length > 0) {
console.log(`Applying contributor-based labels: ${contributorLabels.join(', ')}`);
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: contributorLabels
});
}
} catch (error) {
console.log(`Error applying contributor labels: ${error.message}`);
}
# Summary step
- name: Label sync summary
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const prNumber = context.payload.pull_request.number;
// Get current labels on PR
const pr = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber
});
const currentLabels = pr.data.labels.map(label => label.name);
console.log('='.repeat(50));
console.log('PR Label Sync Complete');
console.log('='.repeat(50));
console.log(`Current labels on PR #${prNumber}:`);
console.log(currentLabels.join(', ') || 'No labels');
console.log('='.repeat(50));