Project Request: Open SWE #72
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Project Request | |
on: | |
issues: | |
types: [opened, edited] | |
env: | |
GH_TOKEN: ${{ secrets.AGENT_TOKEN }} | |
jobs: | |
process-project-request: | |
if: contains(github.event.issue.title, 'Project Request:') | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v3 | |
- name: Set up Python | |
uses: actions/setup-python@v4 | |
with: | |
python-version: '3.10' | |
- name: Install dependencies | |
run: pip install -r requirements.txt | |
- name: Parse issue body | |
id: parse-issue | |
uses: actions/github-script@v6 | |
with: | |
script: | | |
const issueBody = context.payload.issue.body; | |
const issueAuthorId = context.payload.issue.user.login; | |
// First remove HTML comments from the issue body | |
const bodyWithoutComments = issueBody.replace(/<!--[\s\S]*?-->/g, ''); | |
// Extract Project Information | |
// Project name | |
const projectNameMatch = bodyWithoutComments.match(/- Project name:([^\n]+)/i); | |
const projectName = projectNameMatch ? projectNameMatch[1].trim() : null; | |
// Github URL | |
const githubUrlMatch = bodyWithoutComments.match(/- Github URL:([^\n]+)/i); | |
const githubUrl = githubUrlMatch ? githubUrlMatch[1].trim() : null; | |
// Homepage URL | |
const homepageUrlMatch = bodyWithoutComments.match(/- Homepage URL:([^\n]+)/i); | |
const homepageUrl = homepageUrlMatch ? homepageUrlMatch[1].trim() : null; | |
// Logo URL | |
const logoUrlMatch = bodyWithoutComments.match(/- Logo URL:([^\n]+)/i); | |
const logoUrl = logoUrlMatch ? logoUrlMatch[1].trim() : null; | |
// Logo Name (optional) | |
const logoNameMatch = bodyWithoutComments.match(/- Logo Name:([^\n]+)/i); | |
const logoName = logoNameMatch ? logoNameMatch[1].trim() : null; | |
// Extract Category - Find the first checked box with [x] and its parent category | |
let category = null; | |
const lines = bodyWithoutComments.split('\n'); | |
let parentCategory = null; | |
for (let i = 0; i < lines.length; i++) { | |
const line = lines[i].trim(); | |
// Check if this is a main category line | |
if (line.startsWith('- ') && !line.includes('[')) { | |
parentCategory = line.substring(2).trim(); | |
} | |
// Check if this is a checked subcategory | |
if (line.match(/- \[x\] (.+)/)) { | |
const subcategory = line.match(/- \[x\] (.+)/)[1].trim(); | |
if (parentCategory) { | |
category = `${parentCategory}/${subcategory}`; | |
break; | |
} else { | |
category = subcategory; | |
break; | |
} | |
} | |
} | |
// Set outputs | |
core.setOutput('repo-url', githubUrl); | |
core.setOutput('project-name', projectName); | |
core.setOutput('category', category); | |
core.setOutput('logo-url', logoUrl); | |
core.setOutput('logo-name', logoName); | |
core.setOutput('homepage-url', homepageUrl); | |
core.setOutput("author-id", issueAuthorId); | |
// Log the extracted information | |
console.log(`Github URL: ${githubUrl}`); | |
console.log(`Project Name: ${projectName}`); | |
console.log(`Homepage URL: ${homepageUrl}`); | |
console.log(`Logo URL: ${logoUrl}`); | |
console.log(`Logo Name: ${logoName}`); | |
console.log(`Category: ${category}`); | |
console.log(`Author ID: ${issueAuthorId}`); | |
// Define README_ONLY_CATEGORIES | |
const README_ONLY_CATEGORIES = ["MCP/MCP Server", "MCP/MCP Client"]; | |
// Check if the category is in README_ONLY_CATEGORIES | |
const isReadmeOnly = README_ONLY_CATEGORIES.some(c => c.toLowerCase() === category?.toLowerCase()); | |
// Check if we have all required information | |
if (!githubUrl || !projectName || !category) { | |
core.setFailed('Missing required information in the issue'); | |
await github.rest.issues.createComment({ | |
issue_number: context.issue.number, | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
body: 'β Could not process this request. Please make sure you have provided the GitHub repo URL, project name, and selected a category.' | |
}); | |
return false; | |
} | |
// For non-README_ONLY_CATEGORIES, check for homepage_url | |
if (!isReadmeOnly && !homepageUrl) { | |
core.setFailed('Missing required information in the issue'); | |
await github.rest.issues.createComment({ | |
issue_number: context.issue.number, | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
body: `β Could not process this request. Please make sure you have provided the homepage URL.` | |
}); | |
return false; | |
} | |
return true; | |
- name: Check for existing PR | |
if: steps.parse-issue.outputs.result == 'true' | |
id: check-pr | |
uses: actions/github-script@v6 | |
with: | |
github-token: ${{ secrets.AGENT_TOKEN }} | |
script: | | |
const { owner, repo } = context.repo; | |
const issueNumber = context.issue.number; | |
const branchName = `add-project-issue-${issueNumber}`; | |
// Search for existing PRs that reference this issue | |
const prs = await github.rest.pulls.list({ | |
owner, | |
repo, | |
state: 'open' | |
}); | |
// Look for PRs with the expected branch name or that reference this issue | |
let existingPR = null; | |
for (const pr of prs.data) { | |
if (pr.head.ref === branchName || pr.body.includes(`fixes #${issueNumber}`)) { | |
existingPR = pr; | |
break; | |
} | |
} | |
if (existingPR) { | |
console.log(`Found existing PR #${existingPR.number} for issue #${issueNumber}`); | |
core.setOutput('pr-exists', 'true'); | |
core.setOutput('pr-number', existingPR.number.toString()); | |
} else { | |
console.log(`No existing PR found for issue #${issueNumber}`); | |
core.setOutput('pr-exists', 'false'); | |
} | |
// Always set the branch name for later steps | |
core.setOutput('branch-name', branchName); | |
- name: Create or update branch | |
if: steps.parse-issue.outputs.result == 'true' | |
run: | | |
git config --global user.name "InftyAI-Agent" | |
git config --global user.email "[email protected]" | |
BRANCH_NAME="${{ steps.check-pr.outputs.branch-name }}" | |
# Check if the branch already exists on remote | |
if git ls-remote --heads origin $BRANCH_NAME | grep -q $BRANCH_NAME; then | |
echo "Branch $BRANCH_NAME already exists on remote, updating it" | |
git fetch origin | |
git checkout $BRANCH_NAME || git checkout -b $BRANCH_NAME --track origin/$BRANCH_NAME | |
# Reset to main to get latest changes and avoid conflicts | |
git reset --hard origin/main | |
else | |
echo "Creating new branch $BRANCH_NAME" | |
git checkout -b $BRANCH_NAME | |
fi | |
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV | |
- name: Run project_request.py script | |
run: | | |
# Define README_ONLY_CATEGORIES | |
README_ONLY_CATEGORIES=("MCP/MCP Server" "MCP/MCP Client") | |
CATEGORY="${{ steps.parse-issue.outputs.category }}" | |
# Check if category is in README_ONLY_CATEGORIES | |
IS_README_ONLY=false | |
for c in "${README_ONLY_CATEGORIES[@]}"; do | |
if [ "${c,,}" = "${CATEGORY,,}" ]; then | |
IS_README_ONLY=true | |
break | |
fi | |
done | |
# Build command based on category type | |
CMD="python project_request.py \ | |
--category \"$CATEGORY\" \ | |
--repo_url \"${{ steps.parse-issue.outputs.repo-url }}\" \ | |
--name \"${{ steps.parse-issue.outputs.project-name }}\"" | |
# Add logo_url and homepage_url if provided or required | |
if [ "$IS_README_ONLY" = false ] || [ -n "${{ steps.parse-issue.outputs.logo-url }}" ]; then | |
CMD="$CMD --logo_url \"${{ steps.parse-issue.outputs.logo-url }}\"" | |
fi | |
if [ "$IS_README_ONLY" = false ] || [ -n "${{ steps.parse-issue.outputs.homepage-url }}" ]; then | |
CMD="$CMD --homepage_url \"${{ steps.parse-issue.outputs.homepage-url }}\"" | |
fi | |
# Add logo_name if provided | |
if [ -n "${{ steps.parse-issue.outputs.logo-name }}" ]; then | |
CMD="$CMD --logo_name \"${{ steps.parse-issue.outputs.logo-name }}\"" | |
fi | |
echo "Running command: $CMD" | |
eval $CMD | |
- name: Commit changes | |
env: | |
ISSUE_AUTHOR: ${{ steps.parse-issue.outputs.author-id }} | |
run: | | |
git add . | |
git commit -m "Add ${{ steps.parse-issue.outputs.repo-url }} to ${{ steps.parse-issue.outputs.category }} category | |
Co-authored-by: $ISSUE_AUTHOR <[email protected]>" | |
git remote set-url origin https://x-access-token:${GH_TOKEN}@github.com/InftyAI/Awesome-LLMOps.git | |
# Check if we need to force push (if branch already exists) | |
if git ls-remote --heads origin $BRANCH_NAME | grep -q $BRANCH_NAME; then | |
git push --force origin $BRANCH_NAME | |
else | |
git push --set-upstream origin $BRANCH_NAME | |
fi | |
- name: Create or Update Pull Request | |
uses: actions/github-script@v6 | |
with: | |
github-token: ${{ secrets.AGENT_TOKEN }} | |
script: | | |
const { owner, repo } = context.repo; | |
const issueNumber = context.issue.number; | |
const branchName = process.env.BRANCH_NAME; | |
const prExists = '${{ steps.check-pr.outputs.pr-exists }}' === 'true'; | |
const existingPrNumber = '${{ steps.check-pr.outputs.pr-number }}'; | |
const repoUrl = '${{ steps.parse-issue.outputs.repo-url }}'; | |
const category = '${{ steps.parse-issue.outputs.category }}'; | |
// Get the repository name from the URL | |
const repoName = repoUrl.split('/').pop(); | |
// Get the user who created the issue | |
const issue = await github.rest.issues.get({ | |
owner, | |
repo, | |
issue_number: issueNumber | |
}); | |
const issueAuthor = issue.data.user.login; | |
let pr; | |
if (prExists) { | |
// PR already exists, no need to create a new one | |
console.log(`Using existing PR #${existingPrNumber}`); | |
// Add comment to the PR about the update | |
await github.rest.issues.createComment({ | |
issue_number: parseInt(existingPrNumber), | |
owner, | |
repo, | |
body: `β»οΈ PR updated with latest changes from issue #${issueNumber}` | |
}); | |
// Add comment to the issue | |
await github.rest.issues.createComment({ | |
issue_number: issueNumber, | |
owner, | |
repo, | |
body: `β Pull Request #${existingPrNumber} has been updated with your changes` | |
}); | |
} else { | |
// Create a new PR | |
pr = await github.rest.pulls.create({ | |
owner, | |
repo, | |
title: `Add ${repoName} to ${category}`, | |
body: `fixes #${issueNumber}, | |
Co-authored-by: @${issueAuthor}`, | |
head: branchName, | |
base: 'main' | |
}); | |
// Add comment to the issue | |
await github.rest.issues.createComment({ | |
issue_number: issueNumber, | |
owner, | |
repo, | |
body: `β Pull Request created: #${pr.data.number}` | |
}); | |
} |