Add My Project #45
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: Add Project from Issue | |
| on: | |
| issues: | |
| types: [labeled] | |
| permissions: | |
| contents: write | |
| issues: write | |
| pull-requests: write | |
| jobs: | |
| restrict-and-add-project: | |
| runs-on: ubuntu-latest | |
| steps: | |
| # Checkout repository | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| # Define allowed and restricted labels | |
| - name: Define label rules | |
| run: | | |
| echo "RESTRICTED=approved,security,release-ready" >> $GITHUB_ENV | |
| echo "ALLOWED=bug,question,help wanted,enhancement,Music,Video,Chatbot" >> $GITHUB_ENV | |
| echo "MAINTAINERS=arinagrawal05" >> $GITHUB_ENV | |
| # Enforce label restrictions | |
| - name: Enforce label restrictions | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| LABEL="${{ github.event.label.name }}" | |
| SENDER="${{ github.event.sender.login }}" | |
| ISSUE_NUMBER="${{ github.event.issue.number }}" | |
| IFS=',' read -ra RESTRICTED_ARRAY <<< "$RESTRICTED" | |
| IFS=',' read -ra ALLOWED_ARRAY <<< "$ALLOWED" | |
| IFS=',' read -ra MAINTAINERS_ARRAY <<< "$MAINTAINERS" | |
| if [[ " ${RESTRICTED_ARRAY[*]} " =~ " $LABEL " ]] && [[ ! " ${MAINTAINERS_ARRAY[*]} " =~ " $SENDER " ]]; then | |
| echo "Restricted label '$LABEL' added by non-maintainer. Removing..." | |
| gh issue edit $ISSUE_NUMBER --remove-label "$LABEL" | |
| gh issue comment $ISSUE_NUMBER --body "Hi @$SENDER, the label '$LABEL' is restricted to maintainers and has been removed." | |
| exit 0 | |
| fi | |
| if [[ ! " ${RESTRICTED_ARRAY[*]} " =~ " $LABEL " ]] && [[ ! " ${ALLOWED_ARRAY[*]} " =~ " $LABEL " ]]; then | |
| echo "Label '$LABEL' is not allowed. Removing..." | |
| gh issue edit $ISSUE_NUMBER --remove-label "$LABEL" | |
| gh issue comment $ISSUE_NUMBER --body "Hi @$SENDER, the label '$LABEL' is not allowed and has been removed." | |
| exit 0 | |
| fi | |
| # Extract project info (regex based, case-insensitive) | |
| - name: Save issue body | |
| if: ${{ github.event.label.name == 'approved' && contains(env.MAINTAINERS, github.event.sender.login) }} | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh issue view ${{ github.event.issue.number }} --json body -q '.body' > issue_body.txt | |
| - name: Extract project info with Python | |
| if: ${{ github.event.label.name == 'approved' && contains(env.MAINTAINERS, github.event.sender.login) }} | |
| run: | | |
| python3 <<EOF | |
| import os, re | |
| with open("issue_body.txt", encoding="utf-8") as f: | |
| body = f.read() | |
| def extract(pattern, default=""): | |
| m = re.search(pattern, body, re.I) | |
| return m.group(1).strip() if m else default | |
| name = extract(r"Project Name[:\s]*([\s\S]*?)(?:\n|$)") | |
| repo = extract(r"Repository URL[:\s]*([^\s]+)") | |
| website = extract(r"Project Website URL[:\s]*([^\s]+)") | |
| desc = extract(r"Short Description[:\s]*([\s\S]*?)(?:\n|$)") | |
| category = extract(r"Category[:\s]*([\w\s]+)", "Other").title() | |
| with open(os.environ['GITHUB_ENV'], 'a') as f: | |
| f.write(f'NAME={name}\n') | |
| f.write(f'REPO={repo}\n') | |
| f.write(f'WEBSITE={website}\n') | |
| f.write(f'DESC={desc}\n') | |
| f.write(f'CATEGORY={category}\n') | |
| print(f"Extracted project info: {name}, {repo}, {website}, {desc}, {category}") | |
| EOF | |
| - name: Add project to README | |
| if: ${{ github.event.label.name == 'approved' && contains(env.MAINTAINERS, github.event.sender.login) }} | |
| run: | | |
| python3 <<EOF | |
| import os, re | |
| # Read environment variables | |
| name = os.environ.get('NAME', '') | |
| repo = os.environ.get('REPO', '') | |
| website = os.environ.get('WEBSITE', '') | |
| desc = os.environ.get('DESC', '') | |
| category = os.environ.get('CATEGORY', 'Other') | |
| # Read README | |
| with open('README.md', 'r', encoding='utf-8') as f: | |
| readme = f.read() | |
| # Create new row | |
| repo_link = f'[Repo]({repo})' if repo else '' | |
| website_link = f'[Website]({website})' if website else '' | |
| links = ' | '.join(filter(None, [repo_link, website_link])) | |
| new_row = f'| {name} | {desc} | {links} | {category} |\n' | |
| # Find the table and add row | |
| # Look for category section header or end of table | |
| category_pattern = rf'(###\s*{re.escape(category)}.*?\n.*?\n)((?:\|.*\n)+)' | |
| match = re.search(category_pattern, readme, re.IGNORECASE) | |
| if match: | |
| # Add to existing category | |
| table_end = match.end() | |
| readme = readme[:table_end] + new_row + readme[table_end:] | |
| else: | |
| # Try to add to a general table or at the end | |
| # Look for any markdown table | |
| table_pattern = r'(\|.*\|.*\n\|[\s\-:|]+\|.*\n)((?:\|.*\n)*)' | |
| match = re.search(table_pattern, readme) | |
| if match: | |
| table_end = match.end() | |
| readme = readme[:table_end] + new_row + readme[table_end:] | |
| # Write back | |
| with open('README.md', 'w', encoding='utf-8') as f: | |
| f.write(readme) | |
| print(f"Added project to README: {name}") | |
| EOF | |
| # Create Pull Request | |
| - name: Create Pull Request | |
| if: ${{ github.event.label.name == 'approved' && contains(env.MAINTAINERS, github.event.sender.login) }} | |
| id: create_pr | |
| uses: peter-evans/create-pull-request@v7 | |
| with: | |
| branch: add-project-${{ github.event.issue.number }} | |
| title: 'Add project' | |
| body: 'This PR adds a new project from issue #${{ github.event.issue.number }}' | |
| commit-message: "Add project: ${{ env.NAME }}" | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| delete-branch: true | |
| # Merge PR, delete branch, and close issue | |
| - name: Merge PR, delete branch, and close issue | |
| if: ${{ github.event.label.name == 'approved' && contains(env.MAINTAINERS, github.event.sender.login) }} | |
| env: | |
| GH_TOKEN: ${{ secrets.MERGE_TOKEN }} | |
| run: | | |
| PR_NUMBER=$(gh pr list --state open --head add-project-${{ github.event.issue.number }} --json number -q '.[0].number') | |
| if [ "$PR_NUMBER" != "null" ] && [ -n "$PR_NUMBER" ]; then | |
| echo "Merging PR #$PR_NUMBER..." | |
| gh pr merge $PR_NUMBER --squash --admin --delete-branch | |
| gh issue comment ${{ github.event.issue.number }} --body "Project added, PR merged, branch deleted. 🎉" | |
| gh issue close ${{ github.event.issue.number }} | |
| else | |
| echo "No open PR found for add-project-${{ github.event.issue.number }}" | |
| fi |