刚刚加入,怎么就突然没了? #14
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: Manage Gist from Issue Comments | |
| on: | |
| issue_comment: | |
| types: [created] | |
| jobs: | |
| manage-gist: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| issues: write # Required to post comments on issues | |
| contents: read # Required to checkout repository | |
| # Only run if the comment contains ADD or DELETE command AND the comment author is the repository owner | |
| if: | | |
| github.event.comment.user.login == github.repository_owner && | |
| (contains(github.event.comment.body, 'ADD') || | |
| contains(github.event.comment.body, 'DELETE')) | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.x' | |
| - name: Install dependencies | |
| run: | | |
| pip install requests | |
| - name: Process comment command | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GIST_TOKEN: ${{ secrets.GIST_TOKEN }} | |
| GIST_ID: adf8f300dc50a61a965bdcc6ef0aecb3 | |
| COMMENT_BODY: ${{ github.event.comment.body }} | |
| ISSUE_NUMBER: ${{ github.event.issue.number }} | |
| REPO_FULL_NAME: ${{ github.repository }} | |
| run: | | |
| python3 << 'EOF' | |
| import os | |
| import re | |
| import json | |
| import requests | |
| import sys | |
| def check_url_accessible(url): | |
| """Check if URL is accessible""" | |
| try: | |
| response = requests.head(url, timeout=10, allow_redirects=True) | |
| # Only consider 2xx status codes as truly accessible | |
| return 200 <= response.status_code < 300 | |
| except requests.exceptions.RequestException: | |
| try: | |
| response = requests.get(url, timeout=10, allow_redirects=True, stream=True) | |
| # Only consider 2xx status codes as truly accessible, without downloading the full body | |
| status_code = response.status_code | |
| response.close() | |
| return 200 <= status_code < 300 | |
| except requests.exceptions.RequestException: | |
| return False | |
| def get_gist_file(gist_id, filename, token): | |
| """Fetch gist file content""" | |
| url = f"https://api.github.com/gists/{gist_id}" | |
| headers = { | |
| "Authorization": f"Bearer {token}", | |
| "Accept": "application/vnd.github.v3+json" | |
| } | |
| response = requests.get(url, headers=headers) | |
| if response.status_code != 200: | |
| return None | |
| gist_data = response.json() | |
| if filename in gist_data.get('files', {}): | |
| content = gist_data['files'][filename]['content'] | |
| try: | |
| return json.loads(content) | |
| except json.JSONDecodeError: | |
| return [] | |
| return [] | |
| def update_gist_file(gist_id, filename, content, token): | |
| """Update gist file content""" | |
| url = f"https://api.github.com/gists/{gist_id}" | |
| headers = { | |
| "Authorization": f"Bearer {token}", | |
| "Accept": "application/vnd.github.v3+json" | |
| } | |
| data = { | |
| "files": { | |
| filename: { | |
| "content": json.dumps(content, indent=2, ensure_ascii=False) | |
| } | |
| } | |
| } | |
| response = requests.patch(url, headers=headers, json=data) | |
| if response.status_code != 200: | |
| # Log detailed error information to help diagnose failures | |
| try: | |
| error_detail = response.json() | |
| except ValueError: | |
| error_detail = response.text | |
| print( | |
| f"Error: Failed to update gist {gist_id}. " | |
| f"Status: {response.status_code}, Response: {error_detail}", | |
| file=sys.stderr, | |
| ) | |
| return False | |
| return True | |
| def post_comment(repo, issue_number, message, token): | |
| """Post a comment to the issue""" | |
| url = f"https://api.github.com/repos/{repo}/issues/{issue_number}/comments" | |
| headers = { | |
| "Authorization": f"Bearer {token}", | |
| "Accept": "application/vnd.github.v3+json" | |
| } | |
| data = {"body": message} | |
| response = requests.post(url, headers=headers, json=data) | |
| if response.status_code not in [200, 201]: | |
| print(f"Warning: Failed to post comment. Status: {response.status_code}") | |
| def close_issue(repo, issue_number, token): | |
| """Close an issue""" | |
| url = f"https://api.github.com/repos/{repo}/issues/{issue_number}" | |
| headers = { | |
| "Authorization": f"Bearer {token}", | |
| "Accept": "application/vnd.github.v3+json" | |
| } | |
| data = {"state": "closed"} | |
| response = requests.patch(url, headers=headers, json=data) | |
| if response.status_code not in [200, 201]: | |
| print(f"Warning: Failed to close issue. Status: {response.status_code}") | |
| else: | |
| print(f"Successfully closed issue #{issue_number}") | |
| # Get environment variables | |
| gist_token = os.environ.get('GIST_TOKEN') | |
| github_token = os.environ.get('GITHUB_TOKEN') | |
| gist_id = os.environ.get('GIST_ID') | |
| comment_body = os.environ.get('COMMENT_BODY', '') | |
| issue_number = os.environ.get('ISSUE_NUMBER') | |
| repo = os.environ.get('REPO_FULL_NAME') | |
| # Validate required environment variables | |
| if not gist_token: | |
| print("Error: GIST_TOKEN secret not found") | |
| sys.exit(1) | |
| if not github_token: | |
| print("Error: GITHUB_TOKEN not found") | |
| sys.exit(1) | |
| if not gist_id: | |
| print("Error: GIST_ID not configured") | |
| sys.exit(1) | |
| if not issue_number or not repo: | |
| print("Error: Issue context not available") | |
| sys.exit(1) | |
| # Parse comment for ADD or DELETE commands | |
| # Format: ADD <section> <URL> or DELETE <section> <URL> | |
| add_pattern = r'ADD\s+(\S+)\s+(\S+)' | |
| delete_pattern = r'DELETE\s+(\S+)\s+(\S+)' | |
| add_match = re.search(add_pattern, comment_body) | |
| delete_match = re.search(delete_pattern, comment_body) | |
| if add_match: | |
| section = add_match.group(1) | |
| url = add_match.group(2) | |
| filename = f"{section}.json" | |
| print(f"Processing ADD command: section={section}, url={url}") | |
| # Check if URL is accessible | |
| if not check_url_accessible(url): | |
| message = f"❌ URL is not accessible: {url}" | |
| print(message) | |
| post_comment(repo, issue_number, message, github_token) | |
| sys.exit(1) | |
| # Get current gist content | |
| current_data = get_gist_file(gist_id, filename, gist_token) | |
| if current_data is None: | |
| current_data = [] | |
| # Add URL if not already present | |
| if url not in current_data: | |
| current_data.append(url) | |
| # Update gist | |
| if update_gist_file(gist_id, filename, current_data, gist_token): | |
| message = f"✅ Successfully added `{url}` to `{section}.json`" | |
| print(message) | |
| post_comment(repo, issue_number, message, github_token) | |
| close_issue(repo, issue_number, github_token) | |
| else: | |
| message = f"❌ Failed to update gist file `{section}.json`" | |
| print(message) | |
| post_comment(repo, issue_number, message, github_token) | |
| sys.exit(1) | |
| else: | |
| message = f"ℹ️ URL `{url}` already exists in `{section}.json`" | |
| print(message) | |
| post_comment(repo, issue_number, message, github_token) | |
| close_issue(repo, issue_number, github_token) | |
| elif delete_match: | |
| section = delete_match.group(1) | |
| url = delete_match.group(2) | |
| filename = f"{section}.json" | |
| print(f"Processing DELETE command: section={section}, url={url}") | |
| # Get current gist content | |
| current_data = get_gist_file(gist_id, filename, gist_token) | |
| if current_data is None: | |
| current_data = [] | |
| # Remove URL if present | |
| if url in current_data: | |
| current_data.remove(url) | |
| # Update gist | |
| if update_gist_file(gist_id, filename, current_data, gist_token): | |
| message = f"✅ Successfully removed `{url}` from `{section}.json`" | |
| print(message) | |
| post_comment(repo, issue_number, message, github_token) | |
| close_issue(repo, issue_number, github_token) | |
| else: | |
| message = f"❌ Failed to update gist file `{section}.json`" | |
| print(message) | |
| post_comment(repo, issue_number, message, github_token) | |
| sys.exit(1) | |
| else: | |
| message = f"ℹ️ URL `{url}` not found in `{section}.json`" | |
| print(message) | |
| post_comment(repo, issue_number, message, github_token) | |
| close_issue(repo, issue_number, github_token) | |
| else: | |
| print("No valid ADD or DELETE command found") | |
| EOF |