Skip to content

Bounty Monitor

Bounty Monitor #489

name: Bounty Monitor
on:
workflow_dispatch:
schedule:
- cron: "10 * * * *"
permissions:
contents: read
jobs:
monitor:
runs-on: ubuntu-latest
steps:
- name: Validate secrets
env:
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
run: |
if [ -z "$TELEGRAM_BOT_TOKEN" ] || [ -z "$TELEGRAM_CHAT_ID" ]; then
echo "Missing TELEGRAM_BOT_TOKEN or TELEGRAM_CHAT_ID"
exit 1
fi
- name: Build status message
id: status
run: |
python - <<'PY'
import json
import urllib.request
from datetime import datetime, timezone
targets = [
{
"label": "iota_498",
"issue_repo": "iotaledger/iota-rust-sdk",
"issue": 498,
"pr_repo": "iotaledger/iota-rust-sdk",
"pr": 569,
},
{
"label": "iota_515",
"issue_repo": "iotaledger/iota-rust-sdk",
"issue": 515,
"pr_repo": "iotaledger/iota-rust-sdk",
"pr": 570,
},
{
"label": "iota_501",
"issue_repo": "iotaledger/iota-rust-sdk",
"issue": 501,
"pr_repo": "iotaledger/iota-rust-sdk",
"pr": 571,
},
{
"label": "iota_510",
"issue_repo": "iotaledger/iota-rust-sdk",
"issue": 510,
"pr_repo": "iotaledger/iota-rust-sdk",
"pr": 572,
},
{
"label": "rustchain_123",
"issue_repo": "Scottcjn/rustchain-bounties",
"issue": 123,
"pr_repo": "Scottcjn/Rustchain",
"pr": 115,
},
{
"label": "rustchain_122_rustchain",
"issue_repo": "Scottcjn/rustchain-bounties",
"issue": 122,
"pr_repo": "Scottcjn/Rustchain",
"pr": 116,
},
{
"label": "rustchain_122_bottube",
"issue_repo": "Scottcjn/rustchain-bounties",
"issue": 122,
"pr_repo": "Scottcjn/bottube",
"pr": 94,
},
{
"label": "rustchain_122_ramcoffers",
"issue_repo": "Scottcjn/rustchain-bounties",
"issue": 122,
"pr_repo": "Scottcjn/ram-coffers",
"pr": 1,
},
{
"label": "rustchain_72_faq",
"issue_repo": "Scottcjn/rustchain-bounties",
"issue": 72,
"pr_repo": "Scottcjn/Rustchain",
"pr": 117,
},
]
def get(url):
req = urllib.request.Request(
url,
headers={
"Accept": "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
"User-Agent": "job-subscription-monitor",
},
)
with urllib.request.urlopen(req, timeout=20) as resp:
return json.loads(resp.read().decode("utf-8"))
now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M UTC")
lines = [f"[Bounty Monitor] {now}"]
payout_ready = []
for target in targets:
issue_no = target["issue"]
pr_no = target["pr"]
label = target["label"]
issue_repo = target["issue_repo"]
pr_repo = target["pr_repo"]
issue = get(
f"https://api.github.com/repos/{issue_repo}/issues/{issue_no}"
)
pr = get(
f"https://api.github.com/repos/{pr_repo}/pulls/{pr_no}"
)
issue_state = issue.get("state", "unknown")
pr_state = pr.get("state", "unknown")
pr_merged = bool(pr.get("merged", False))
mergeable_state = pr.get("mergeable_state", "unknown")
review_comments = pr.get("review_comments", 0)
comments = pr.get("comments", 0)
commits = pr.get("commits", 0)
changed_files = pr.get("changed_files", 0)
payout_hint = "wait_for_review"
if pr_merged:
payout_hint = "request_bounty_payout_now"
payout_ready.append(
f"{label}(issue_{issue_repo}#{issue_no}/pr_{pr_repo}#{pr_no})"
)
elif pr_state == "closed":
payout_hint = "pr_closed_without_merge_check_next_action"
elif review_comments > 0 or comments > 0:
payout_hint = "review_feedback_available"
lines.extend(
[
"",
f"{label}:",
f"issue_{issue_no}_state={issue_state}",
f"pr_{pr_no}_state={pr_state}",
f"pr_{pr_no}_merged={str(pr_merged).lower()}",
f"pr_{pr_no}_mergeable_state={mergeable_state}",
f"pr_{pr_no}_review_comments={review_comments}",
f"pr_{pr_no}_comments={comments}",
f"pr_{pr_no}_commits={commits} changed_files={changed_files}",
f"payout_action={payout_hint}",
f"issue=https://github.com/{issue_repo}/issues/{issue_no}",
f"pr=https://github.com/{pr_repo}/pull/{pr_no}",
]
)
lines.extend(
[
"",
"summary:",
f"payout_ready_count={len(payout_ready)}",
f"payout_ready_jobs={', '.join(payout_ready) if payout_ready else 'none'}",
]
)
with open("status_message.txt", "w", encoding="utf-8") as f:
f.write("\n".join(lines))
with open("status_message.txt", "r", encoding="utf-8") as f:
message = f.read()
with open("/tmp/github_output.txt", "w", encoding="utf-8") as f:
f.write("message<<EOF\n")
f.write(message)
f.write("\nEOF\n")
with open("/tmp/github_output.txt", "r", encoding="utf-8") as src, open(
__import__("os").environ["GITHUB_OUTPUT"], "a", encoding="utf-8"
) as dst:
dst.write(src.read())
PY
- name: Send Telegram update
env:
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
MESSAGE: ${{ steps.status.outputs.message }}
run: |
curl -sS -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
--data-urlencode "chat_id=${TELEGRAM_CHAT_ID}" \
--data-urlencode "text=${MESSAGE}" \
--data-urlencode "disable_web_page_preview=true"