diff --git a/.github/workflows/debug-secrets.yml b/.github/workflows/debug-secrets.yml new file mode 100644 index 0000000..44a1202 --- /dev/null +++ b/.github/workflows/debug-secrets.yml @@ -0,0 +1,24 @@ +name: Debug Secrets + +on: + workflow_dispatch: # Manual trigger + push: + branches: [main] # Or remove this if you only want manual + +jobs: + debug: + runs-on: ubuntu-latest + steps: + - name: Check all secrets + env: + GIST_PAT: ${{ secrets.GIST_PAT }} + DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }} + DISCORD_GUILD_ID: ${{ secrets.DISCORD_GUILD_ID }} + DISCORD_APPRENTICE_ROLE_ID: ${{ secrets.DISCORD_APPRENTICE_ROLE_ID }} + DISCORD_SENTINEL_ROLE_ID: ${{ secrets.DISCORD_SENTINEL_ROLE_ID }} + run: | + [ -n "$GIST_PAT" ] && echo "✓ GIST_PAT (${#GIST_PAT} chars)" || echo "❌ GIST_PAT missing" + [ -n "$DISCORD_BOT_TOKEN" ] && echo "✓ DISCORD_BOT_TOKEN (${#DISCORD_BOT_TOKEN} chars)" || echo "❌ DISCORD_BOT_TOKEN missing" + [ -n "$DISCORD_GUILD_ID" ] && echo "✓ DISCORD_GUILD_ID ($DISCORD_GUILD_ID)" || echo "❌ DISCORD_GUILD_ID missing" + [ -n "$DISCORD_APPRENTICE_ROLE_ID" ] && echo "✓ DISCORD_APPRENTICE_ROLE_ID ($DISCORD_APPRENTICE_ROLE_ID)" || echo "❌ DISCORD_APPRENTICE_ROLE_ID missing" + [ -n "$DISCORD_SENTINEL_ROLE_ID" ] && echo "✓ DISCORD_SENTINEL_ROLE_ID ($DISCORD_SENTINEL_ROLE_ID)" || echo "❌ DISCORD_SENTINEL_ROLE_ID missing" diff --git a/.github/workflows/manual-assign-role.yml b/.github/workflows/manual-assign-role.yml new file mode 100644 index 0000000..daa779e --- /dev/null +++ b/.github/workflows/manual-assign-role.yml @@ -0,0 +1,82 @@ +name: Manual Discord Role Assignment + +on: + workflow_dispatch: + inputs: + discord_user_id: + description: 'Discord User ID (17-19 digits)' + required: true + type: string + role_name: + description: 'Role to assign' + required: true + type: choice + options: + - Apprentice + - Sentinel + - Knights + +jobs: + assign-role: + runs-on: ubuntu-latest + + steps: + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install requests + run: pip install requests + + - name: Assign Discord Role + env: + DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }} + DISCORD_GUILD_ID: ${{ secrets.DISCORD_GUILD_ID }} + DISCORD_USER_ID: ${{ inputs.discord_user_id }} + DISCORD_APPRENTICE_ROLE_ID: ${{ secrets.DISCORD_APPRENTICE_ROLE_ID }} + DISCORD_SENTINEL_ROLE_ID: ${{ secrets.DISCORD_SENTINEL_ROLE_ID }} + DISCORD_KNIGHTS_ROLE_ID: ${{ secrets.DISCORD_KNIGHTS_ROLE_ID }} + ROLE_NAME: ${{ inputs.role_name }} + run: | + python << 'EOF' + import os + import requests + + # Get inputs + bot_token = os.environ['DISCORD_BOT_TOKEN'] + guild_id = os.environ['DISCORD_GUILD_ID'] + user_id = os.environ['DISCORD_USER_ID'] + role_name = os.environ['ROLE_NAME'] + + # Determine role ID + if role_name == 'Apprentice': + role_id = os.environ['DISCORD_APPRENTICE_ROLE_ID'] + elif role_name == 'Sentinel': + role_id = os.environ['DISCORD_SENTINEL_ROLE_ID'] + elif role_name == 'Knights': + role_id = os.environ['DISCORD_KNIGHTS_ROLE_ID'] + else: + print(f"✗ Unknown role: {role_name}") + exit(1) + + print(f"Assigning {role_name} role (ID: {role_id}) to user {user_id}") + + # Make Discord API request + url = f"https://discord.com/api/v10/guilds/{guild_id}/members/{user_id}/roles/{role_id}" + headers = { + "Authorization": f"Bot {bot_token}", + "Content-Type": "application/json" + } + + response = requests.put(url, headers=headers, timeout=10) + + # Log result + if response.status_code == 204: + print(f"✓ Successfully assigned {role_name} role") + exit(0) + else: + print(f"✗ Failed: {response.status_code}") + print(f"Response: {response.text}") + exit(1) + EOF diff --git a/.github/workflows/manual-reward.yml b/.github/workflows/manual-reward.yml new file mode 100644 index 0000000..927a87d --- /dev/null +++ b/.github/workflows/manual-reward.yml @@ -0,0 +1,24 @@ +name: Manual Reward Input + +on: + workflow_dispatch: + inputs: + metamask: + description: "MetaMask Wallet Address" + required: true + type: string + + tokens: + description: "Number of Tokens to Reward" + required: true + type: number + +jobs: + reward: + runs-on: ubuntu-latest + + steps: + - name: Print inputs (dummy check) + run: | + echo "Wallet: ${{ github.event.inputs.metamask }}" + echo "Tokens: ${{ github.event.inputs.tokens }}" diff --git a/.github/workflows/onboard-first-comment-trigger.yml b/.github/workflows/onboard-first-comment-trigger.yml index 10ccb75..6babf01 100644 --- a/.github/workflows/onboard-first-comment-trigger.yml +++ b/.github/workflows/onboard-first-comment-trigger.yml @@ -65,35 +65,16 @@ jobs: # Only post comment if user is NOT already onboarded - name: Comment asking for Discord ID and wallet if: steps.check_existing.outputs.exists == 'false' - uses: actions/github-script@v7 - with: - script: | - const author = context.payload.pull_request.user.login; - const body = `🎉 **Congratulations @${author} on your first merged PR!** - - To complete onboarding and receive your Discord **Apprentice** role, please comment **exactly** in this format: - - \`\`\` - discord: "YOUR_DISCORD_USER_ID" - wallet: "YOUR_WALLET_ADDRESS" - \`\`\` - - **How to find your Discord ID:** - 1. Enable Developer Mode in Discord (Settings → Advanced) - 2. Right-click your username → Copy User ID - - **Wallet format:** Must start with \`0x\` (42 characters total) - - ⚠️ **Important:** - - Only the PR author's comment will be accepted - - You must be in the Discord server to be assigned a role - - **Discord Server:** https://discord.gg/fuuWX4AbJt - - ⏰ **You have 7 days to respond.**`; - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.payload.pull_request.number, - body - }); + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO_NAME: ${{ github.repository }} + PR_NUMBER: ${{ github.event.pull_request.number }} + PR_AUTHOR: ${{ github.event.pull_request.user.login }} + run: | + cd automation + python scripts/discord_manager.py \ + --action ask_info \ + --repo-name "$REPO_NAME" \ + --pr-number $PR_NUMBER \ + --pr-author "$PR_AUTHOR" \ + --github-token "$GITHUB_TOKEN" diff --git a/.github/workflows/promote-trigger.yml b/.github/workflows/promote-trigger.yml index abeb2a9..4fb1f2f 100644 --- a/.github/workflows/promote-trigger.yml +++ b/.github/workflows/promote-trigger.yml @@ -3,16 +3,22 @@ name: Check Promotion to Sentinel on: pull_request: types: [closed] + workflow_dispatch: + inputs: + pr_author: + description: 'GitHub username to check for promotion' + required: true + type: string jobs: promote: # Run after PR is merged to check if promotion is needed - if: github.event.pull_request.merged == true + if: github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch' uses: automation-workflows/contributor-automation/.github/workflows/reusable-promote.yml@main with: - pr_number: ${{ github.event.pull_request.number }} + pr_number: ${{ github.event.pull_request.number || 0 }} repo_name: ${{ github.repository }} - pr_author: ${{ github.event.pull_request.user.login }} + pr_author: ${{ github.event.pull_request.user.login || inputs.pr_author }} secrets: GIST_PAT: ${{ secrets.GIST_PAT }} DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }} diff --git a/.github/workflows/test-contributor-label.yml b/.github/workflows/test-contributor-label.yml new file mode 100644 index 0000000..1576f93 --- /dev/null +++ b/.github/workflows/test-contributor-label.yml @@ -0,0 +1,51 @@ +name: Test Contributor Label + +on: + pull_request_target: + types: [opened, reopened] + +permissions: + contents: read + pull-requests: write + issues: write + +jobs: + label-contributor: + runs-on: ubuntu-latest + steps: + - name: Label contributor type + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const prNumber = context.payload.pull_request.number; + const prAuthor = context.payload.pull_request.user.login; + + console.log(`Checking contributor type for: ${prAuthor}`); + + let label = 'external-contributor'; + + try { + const permissionLevel = await github.rest.repos.getCollaboratorPermissionLevel({ + owner: context.repo.owner, + repo: context.repo.repo, + username: prAuthor + }); + + console.log(`Permission level: ${permissionLevel.data.permission}`); + + if (['admin', 'maintain'].includes(permissionLevel.data.permission)) { + label = 'maintainer'; + } + } catch (error) { + console.log(`Could not check permissions: ${error.message}`); + } + + console.log(`Applying label: ${label}`); + + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + labels: [label] + }); diff --git a/.github/workflows/update-trigger.yml b/.github/workflows/update-trigger.yml index 5f16ca8..b213926 100644 --- a/.github/workflows/update-trigger.yml +++ b/.github/workflows/update-trigger.yml @@ -1,33 +1,66 @@ name: Update Contributor Registry on: - pull_request: + pull_request_target: types: [closed] + workflow_dispatch: jobs: calculate: # Run on any merged PR (not just first-time contributors) - if: github.event.pull_request.merged == true + if: github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read outputs: lines_changed: ${{ steps.calc.outputs.lines_changed }} steps: + - name: Verify secrets configuration + env: + GIST_PAT: ${{ secrets.GIST_PAT }} + DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }} + DISCORD_GUILD_ID: ${{ secrets.DISCORD_GUILD_ID }} + run: | + echo "Checking required secrets..." + + if [ -z "$GIST_PAT" ]; then + echo "❌ GIST_PAT secret is not configured" + exit 1 + else + echo "✓ GIST_PAT is configured (length: ${#GIST_PAT} chars)" + fi + + if [ -z "$DISCORD_BOT_TOKEN" ]; then + echo "⚠️ DISCORD_BOT_TOKEN is not configured (optional for registry update)" + else + echo "✓ DISCORD_BOT_TOKEN is configured (length: ${#DISCORD_BOT_TOKEN} chars)" + fi + + if [ -z "$DISCORD_GUILD_ID" ]; then + echo "⚠️ DISCORD_GUILD_ID is not configured (optional for registry update)" + else + echo "✓ DISCORD_GUILD_ID is configured (value: $DISCORD_GUILD_ID)" + fi + - name: Calculate lines changed id: calc run: | - ADDITIONS=${{ github.event.pull_request.additions }} - DELETIONS=${{ github.event.pull_request.deletions }} + ADDITIONS=${{ github.event.pull_request.additions || 0 }} + DELETIONS=${{ github.event.pull_request.deletions || 0 }} LINES_CHANGED=$((ADDITIONS + DELETIONS)) echo "lines_changed=$LINES_CHANGED" >> $GITHUB_OUTPUT update: needs: calculate + permissions: + contents: write + pull-requests: read uses: automation-workflows/contributor-automation/.github/workflows/reusable-update-registry.yml@main with: - pr_number: ${{ github.event.pull_request.number }} + pr_number: ${{ github.event.pull_request.number || 0 }} repo_name: ${{ github.repository }} - pr_author: ${{ github.event.pull_request.user.login }} - lines_changed: ${{ fromJson(needs.calculate.outputs.lines_changed) }} - pr_labels: ${{ toJson(github.event.pull_request.labels.*.name) }} - secrets: - GIST_PAT: ${{ secrets.GIST_PAT }} \ No newline at end of file + pr_author: ${{ github.event.pull_request.user.login || github.actor }} + lines_changed: ${{ needs.calculate.outputs.lines_changed }} + pr_labels: ${{ toJson(github.event.pull_request.labels.*.name || '[]') }} + secrets: inherit \ No newline at end of file diff --git a/README.md b/README.md index ff412e9..ebab48c 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,33 @@ check 10 check 11 check 12 check 13 - +check 14 +check 15 +check 16 +check 17 +check 18 +check 19 +check 20 +check 21 +check 22 +check 23 +check 24 +check 25 +check 26 +check 27 +check 28 +check 29 +check 30 +check 31 +check 32 +check 33 +check 34 +check 35 +check 36 +check 37 +check 38 +check 40 +check 41