diff --git a/.github/workflows/auto-add-to-project.yml b/.github/workflows/auto-add-to-project.yml new file mode 100644 index 00000000..31a9f8d4 --- /dev/null +++ b/.github/workflows/auto-add-to-project.yml @@ -0,0 +1,17 @@ +name: Auto-add issues and PRs to Project + +on: + issues: + types: [opened, reopened] + pull_request: + types: [opened, reopened] + +jobs: + add-to-project: + runs-on: ubuntu-latest + steps: + - name: Add issue or PR to project + uses: actions/add-to-project@v0.5.0 + with: + project-url: https://github.com/users/Wikid82/projects/7 + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/auto-label-issues.yml b/.github/workflows/auto-label-issues.yml new file mode 100644 index 00000000..87a7b935 --- /dev/null +++ b/.github/workflows/auto-label-issues.yml @@ -0,0 +1,74 @@ +name: Auto-label Issues + +on: + issues: + types: [opened, edited] + +jobs: + auto-label: + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - name: Auto-label based on title and body + uses: actions/github-script@v7 + with: + script: | + const issue = context.payload.issue; + const title = issue.title.toLowerCase(); + const body = issue.body ? issue.body.toLowerCase() : ''; + const labels = []; + + // Priority detection + if (title.includes('[critical]') || body.includes('priority: critical')) { + labels.push('critical'); + } else if (title.includes('[high]') || body.includes('priority: high')) { + labels.push('high'); + } else if (title.includes('[medium]') || body.includes('priority: medium')) { + labels.push('medium'); + } else if (title.includes('[low]') || body.includes('priority: low')) { + labels.push('low'); + } + + // Milestone detection + if (title.includes('[alpha]') || body.includes('milestone: alpha')) { + labels.push('alpha'); + } else if (title.includes('[beta]') || body.includes('milestone: beta')) { + labels.push('beta'); + } else if (title.includes('[post-beta]') || body.includes('milestone: post-beta')) { + labels.push('post-beta'); + } + + // Category detection + if (title.includes('architecture') || body.includes('architecture')) labels.push('architecture'); + if (title.includes('backend') || body.includes('backend')) labels.push('backend'); + if (title.includes('frontend') || body.includes('frontend')) labels.push('frontend'); + if (title.includes('security') || body.includes('security')) labels.push('security'); + if (title.includes('ssl') || title.includes('tls') || body.includes('certificate')) labels.push('ssl'); + if (title.includes('sso') || body.includes('single sign-on')) labels.push('sso'); + if (title.includes('waf') || body.includes('web application firewall')) labels.push('waf'); + if (title.includes('crowdsec') || body.includes('crowdsec')) labels.push('crowdsec'); + if (title.includes('caddy') || body.includes('caddy')) labels.push('caddy'); + if (title.includes('database') || body.includes('database')) labels.push('database'); + if (title.includes('ui') || title.includes('interface')) labels.push('ui'); + if (title.includes('docker') || title.includes('deployment')) labels.push('deployment'); + if (title.includes('monitoring') || title.includes('logging')) labels.push('monitoring'); + if (title.includes('documentation') || title.includes('docs')) labels.push('documentation'); + if (title.includes('test') || body.includes('testing')) labels.push('testing'); + if (title.includes('performance') || body.includes('optimization')) labels.push('performance'); + if (title.includes('plus') || body.includes('premium feature')) labels.push('plus'); + + // Feature detection + if (title.includes('feature') || body.includes('feature request')) labels.push('feature'); + + // Only add labels if we detected any + if (labels.length > 0) { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + labels: labels + }); + + console.log(`Added labels: ${labels.join(', ')}`); + } diff --git a/.github/workflows/create-labels.yml b/.github/workflows/create-labels.yml new file mode 100644 index 00000000..da3abb81 --- /dev/null +++ b/.github/workflows/create-labels.yml @@ -0,0 +1,78 @@ +name: Create Project Labels + +# This workflow only runs manually to set up labels +on: + workflow_dispatch: + +jobs: + create-labels: + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - name: Create all project labels + uses: actions/github-script@v7 + with: + script: | + const labels = [ + // Priority labels + { name: 'critical', color: 'B60205', description: 'Must have for the release, blocks other work' }, + { name: 'high', color: 'D93F0B', description: 'Important feature, should be included' }, + { name: 'medium', color: 'FBCA04', description: 'Nice to have, can be deferred' }, + { name: 'low', color: '0E8A16', description: 'Future enhancement, not urgent' }, + + // Milestone labels + { name: 'alpha', color: '5319E7', description: 'Part of initial alpha release' }, + { name: 'beta', color: '0052CC', description: 'Part of beta release' }, + { name: 'post-beta', color: '006B75', description: 'Post-beta enhancement' }, + + // Category labels + { name: 'architecture', color: 'C5DEF5', description: 'System design and structure' }, + { name: 'backend', color: '1D76DB', description: 'Server-side code' }, + { name: 'frontend', color: '5EBEFF', description: 'UI/UX code' }, + { name: 'feature', color: 'A2EEEF', description: 'New functionality' }, + { name: 'security', color: 'EE0701', description: 'Security-related' }, + { name: 'ssl', color: 'F9D0C4', description: 'SSL/TLS certificates' }, + { name: 'sso', color: 'D4C5F9', description: 'Single Sign-On' }, + { name: 'waf', color: 'B60205', description: 'Web Application Firewall' }, + { name: 'crowdsec', color: 'FF6B6B', description: 'CrowdSec integration' }, + { name: 'caddy', color: '1F6FEB', description: 'Caddy-specific' }, + { name: 'database', color: '006B75', description: 'Database-related' }, + { name: 'ui', color: '7057FF', description: 'User interface' }, + { name: 'deployment', color: '0E8A16', description: 'Docker, installation' }, + { name: 'monitoring', color: 'FEF2C0', description: 'Logging and statistics' }, + { name: 'documentation', color: '0075CA', description: 'Docs and guides' }, + { name: 'testing', color: 'BFD4F2', description: 'Test suite' }, + { name: 'performance', color: 'EDEDED', description: 'Optimization' }, + { name: 'community', color: 'D876E3', description: 'Community building' }, + { name: 'plus', color: 'FFD700', description: 'Premium/"Plus" feature' }, + { name: 'enterprise', color: '8B4513', description: 'Enterprise-grade feature' } + ]; + + for (const label of labels) { + try { + await github.rest.issues.createLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + name: label.name, + color: label.color, + description: label.description + }); + console.log(`✓ Created label: ${label.name}`); + } catch (error) { + if (error.status === 422) { + console.log(`⚠ Label already exists: ${label.name}`); + // Update the label if it exists + await github.rest.issues.updateLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + name: label.name, + color: label.color, + description: label.description + }); + console.log(`✓ Updated label: ${label.name}`); + } else { + console.error(`✗ Error creating label ${label.name}:`, error.message); + } + } + }