From 1aada4d9aa4ab6e0a026c3ff14b6c66701934365 Mon Sep 17 00:00:00 2001 From: plun1331 Date: Sun, 26 Apr 2026 16:58:24 -0700 Subject: [PATCH 01/13] update from main (#11) * fix: escape markdown for game -> discord messages * ci: only tag main branch as latest --- .github/workflows/build.yml | 4 ++-- core/discord_bot.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5604e9e..8c4952b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -100,7 +100,7 @@ jobs: with: images: ${{ env.REGISTRY_IMAGE }} tags: | - type=raw,value=latest + type=raw,value=latest,enable={{is_default_branch}} type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} @@ -114,4 +114,4 @@ jobs: - name: Inspect image run: | - docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }} \ No newline at end of file + docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }} diff --git a/core/discord_bot.py b/core/discord_bot.py index 7afe76c..4c16a18 100644 --- a/core/discord_bot.py +++ b/core/discord_bot.py @@ -299,7 +299,7 @@ async def send_user_message( officer=officer, ) else: - embed = Embed(description=message, colour=0x1ABC9C, timestamp=discord.utils.utcnow()) + embed = Embed(description=discord.utils.escape_markdown(message), colour=0x1ABC9C, timestamp=discord.utils.utcnow()) embed.set_author(name=("🤖 " + username) if command else username, icon_url=head) return await self.send_message(embed=embed, officer=officer) From a98c25fedf3886d5d1f457a66107eabdf0f6638b Mon Sep 17 00:00:00 2001 From: Jacktheguy Date: Sun, 26 Apr 2026 20:25:51 -0400 Subject: [PATCH 02/13] feat: add git SHA tracking and outdated check for Discord bot --- .github/workflows/build.yml | 2 ++ Dockerfile | 6 +++++ core/discord_bot.py | 51 ++++++++++++++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5604e9e..cd396c4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -51,6 +51,8 @@ jobs: uses: docker/build-push-action@v6 with: platforms: ${{ matrix.platform }} + build-args: | + GIT_SHA=${{ github.sha }} labels: ${{ steps.meta.outputs.labels }} tags: ${{ env.REGISTRY_IMAGE }} outputs: type=image,push-by-digest=true,name-canonical=true,push=true diff --git a/Dockerfile b/Dockerfile index 7c08a36..96e8d0b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,11 @@ FROM nikolaik/python-nodejs:python3.13-nodejs25 + +# Store git commit hash +ARG GIT_SHA +ENV GIT_SHA=$GIT_SHA + + # Set the working directory in the container WORKDIR /Bot diff --git a/core/discord_bot.py b/core/discord_bot.py index 7afe76c..4f3bb43 100644 --- a/core/discord_bot.py +++ b/core/discord_bot.py @@ -35,6 +35,40 @@ def emoji_repl(match): def slash_mention_repl(match): return f"/{match.group(1)}" +def get_current_git_sha() -> str: + try: + with open(".git/HEAD", "r") as f: + ref = f.read().strip() + if ref.startswith("ref:"): + ref_path = os.path.join(".git", ref[5:]) + with open(ref_path, "r") as rf: + return rf.read().strip() + else: + return ref + except Exception as e: + print(f"{Color.CYAN}Discord{Color.RESET} > Failed to get git SHA: {e}") + return "unknown" + +def get_latest_commit_sha() -> str: + try: + import subprocess + result = subprocess.run(["git", "rev-parse", "HEAD"], capture_output=True, text=True) + if result.returncode == 0: + return result.stdout.strip() + else: + print(f"{Color.CYAN}Discord{Color.RESET} > Failed to get latest git SHA: {result.stderr}") + return "unknown" + except Exception as e: + print(f"{Color.CYAN}Discord{Color.RESET} > Failed to get latest git SHA: {e}") + return "unknown" + +def is_outdated() -> bool: + current_sha = get_current_git_sha() + latest_sha = get_latest_commit_sha() + if current_sha == "unknown" or latest_sha == "unknown": + return False + return current_sha != latest_sha + class DiscordBridgeBot(commands.Bot): def __init__(self): @@ -229,6 +263,21 @@ async def _send_message(self, *args, **kwargs) -> Union[discord.Message, discord ) return None + is_bot_outdated = is_outdated() + # Add a footer to the embed if the bot is outdated + if is_bot_outdated: + footer_text = "📩 Bridge Update available!" + if 'embed' in kwargs: + embed = kwargs['embed'] + if isinstance(embed, discord.Embed): + if embed.footer.text: + embed.set_footer(text=embed.footer.text + " | " + footer_text) + else: + embed.set_footer(text=footer_text) + else: + kwargs['embed'] = discord.Embed(description=" ", colour=0xFF6347) + kwargs['embed'].set_footer(text=footer_text) + is_officer = kwargs.pop("officer", False) officer_maybe = kwargs.pop("officer_maybe", False) if officer_maybe: @@ -299,7 +348,7 @@ async def send_user_message( officer=officer, ) else: - embed = Embed(description=message, colour=0x1ABC9C, timestamp=discord.utils.utcnow()) + embed = Embed(description=discord.utils.escape_markdown(message), colour=0x1ABC9C, timestamp=discord.utils.utcnow()) embed.set_author(name=("🤖 " + username) if command else username, icon_url=head) return await self.send_message(embed=embed, officer=officer) From 7a496611a0f88c29f19219f4698f2a28066d6e09 Mon Sep 17 00:00:00 2001 From: Jacktheguy Date: Sun, 26 Apr 2026 20:30:07 -0400 Subject: [PATCH 03/13] fix: update git SHA retrieval to use repository path for better compatibility --- core/discord_bot.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/core/discord_bot.py b/core/discord_bot.py index 4f3bb43..636dfb5 100644 --- a/core/discord_bot.py +++ b/core/discord_bot.py @@ -37,10 +37,12 @@ def slash_mention_repl(match): def get_current_git_sha() -> str: try: - with open(".git/HEAD", "r") as f: + repo_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + git_head_path = os.path.join(repo_dir, ".git", "HEAD") + with open(git_head_path, "r") as f: ref = f.read().strip() if ref.startswith("ref:"): - ref_path = os.path.join(".git", ref[5:]) + ref_path = os.path.join(repo_dir, ".git", ref[5:]) with open(ref_path, "r") as rf: return rf.read().strip() else: @@ -52,7 +54,8 @@ def get_current_git_sha() -> str: def get_latest_commit_sha() -> str: try: import subprocess - result = subprocess.run(["git", "rev-parse", "HEAD"], capture_output=True, text=True) + repo_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + result = subprocess.run(["git", "rev-parse", "HEAD"], capture_output=True, text=True, cwd=repo_dir) if result.returncode == 0: return result.stdout.strip() else: From 54eceebf01f4dfac5de743a9cc86c8849a58acfb Mon Sep 17 00:00:00 2001 From: Jacktheguy Date: Sun, 26 Apr 2026 20:35:18 -0400 Subject: [PATCH 04/13] refactor: simplify git SHA retrieval by removing redundant function --- core/discord_bot.py | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/core/discord_bot.py b/core/discord_bot.py index 636dfb5..4413109 100644 --- a/core/discord_bot.py +++ b/core/discord_bot.py @@ -35,23 +35,13 @@ def emoji_repl(match): def slash_mention_repl(match): return f"/{match.group(1)}" -def get_current_git_sha() -> str: - try: - repo_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) - git_head_path = os.path.join(repo_dir, ".git", "HEAD") - with open(git_head_path, "r") as f: - ref = f.read().strip() - if ref.startswith("ref:"): - ref_path = os.path.join(repo_dir, ".git", ref[5:]) - with open(ref_path, "r") as rf: - return rf.read().strip() - else: - return ref - except Exception as e: - print(f"{Color.CYAN}Discord{Color.RESET} > Failed to get git SHA: {e}") - return "unknown" - def get_latest_commit_sha() -> str: + # Check for GIT_SHA environment variable (set during Docker build) + git_sha = os.getenv("GIT_SHA") + if git_sha: + return git_sha + + # Fallback to git command for local development try: import subprocess repo_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) From a48f3f604bf1bb2908acb52fffc627a11610bf06 Mon Sep 17 00:00:00 2001 From: Jacktheguy Date: Sun, 26 Apr 2026 20:39:40 -0400 Subject: [PATCH 05/13] bad --- core/discord_bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/discord_bot.py b/core/discord_bot.py index 4413109..5326da9 100644 --- a/core/discord_bot.py +++ b/core/discord_bot.py @@ -56,7 +56,7 @@ def get_latest_commit_sha() -> str: return "unknown" def is_outdated() -> bool: - current_sha = get_current_git_sha() + current_sha = os.getenv("GIT_SHA", "unknown") latest_sha = get_latest_commit_sha() if current_sha == "unknown" or latest_sha == "unknown": return False From 90ec99b560d9947acc7df165260f28471c71474c Mon Sep 17 00:00:00 2001 From: Jacktheguy Date: Sun, 26 Apr 2026 20:43:33 -0400 Subject: [PATCH 06/13] test update --- core/discord_bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/discord_bot.py b/core/discord_bot.py index 5326da9..2f971d5 100644 --- a/core/discord_bot.py +++ b/core/discord_bot.py @@ -36,7 +36,7 @@ def slash_mention_repl(match): return f"/{match.group(1)}" def get_latest_commit_sha() -> str: - # Check for GIT_SHA environment variable (set during Docker build) + # Check for GIT_SHA environment variable git_sha = os.getenv("GIT_SHA") if git_sha: return git_sha From 687a476ea14b6b9375bc5ebc9257597961b3bcae Mon Sep 17 00:00:00 2001 From: Jacktheguy Date: Sun, 26 Apr 2026 20:45:02 -0400 Subject: [PATCH 07/13] debug --- core/discord_bot.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/discord_bot.py b/core/discord_bot.py index 2f971d5..90a5b08 100644 --- a/core/discord_bot.py +++ b/core/discord_bot.py @@ -56,8 +56,12 @@ def get_latest_commit_sha() -> str: return "unknown" def is_outdated() -> bool: + print(f"{Color.CYAN}Discord{Color.RESET} > Checking for updates...") + # Print the current and latest SHAs for debugging current_sha = os.getenv("GIT_SHA", "unknown") latest_sha = get_latest_commit_sha() + print(f"{Color.CYAN}Discord{Color.RESET} > Current SHA: {current_sha}") + print(f"{Color.CYAN}Discord{Color.RESET} > Latest SHA: {latest_sha}") if current_sha == "unknown" or latest_sha == "unknown": return False return current_sha != latest_sha From eece922868e64d49c4730f046440ea34f94e57a0 Mon Sep 17 00:00:00 2001 From: Jacktheguy Date: Sun, 26 Apr 2026 20:48:11 -0400 Subject: [PATCH 08/13] debug test --- core/discord_bot.py | 1 - 1 file changed, 1 deletion(-) diff --git a/core/discord_bot.py b/core/discord_bot.py index 90a5b08..2d0468b 100644 --- a/core/discord_bot.py +++ b/core/discord_bot.py @@ -57,7 +57,6 @@ def get_latest_commit_sha() -> str: def is_outdated() -> bool: print(f"{Color.CYAN}Discord{Color.RESET} > Checking for updates...") - # Print the current and latest SHAs for debugging current_sha = os.getenv("GIT_SHA", "unknown") latest_sha = get_latest_commit_sha() print(f"{Color.CYAN}Discord{Color.RESET} > Current SHA: {current_sha}") From 1076335eaf0f714b1fbe3545ef8b231fedd8389d Mon Sep 17 00:00:00 2001 From: Jacktheguy Date: Sun, 26 Apr 2026 20:55:10 -0400 Subject: [PATCH 09/13] now we are cooking --- core/discord_bot.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/core/discord_bot.py b/core/discord_bot.py index 2d0468b..f883eeb 100644 --- a/core/discord_bot.py +++ b/core/discord_bot.py @@ -36,16 +36,29 @@ def slash_mention_repl(match): return f"/{match.group(1)}" def get_latest_commit_sha() -> str: - # Check for GIT_SHA environment variable - git_sha = os.getenv("GIT_SHA") - if git_sha: - return git_sha - - # Fallback to git command for local development + """Fetch the latest commit SHA from GitHub on the current branch""" try: import subprocess repo_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) - result = subprocess.run(["git", "rev-parse", "HEAD"], capture_output=True, text=True, cwd=repo_dir) + + # Get current branch name + branch_result = subprocess.run( + ["git", "rev-parse", "--abbrev-ref", "HEAD"], + capture_output=True, + text=True, + cwd=repo_dir + ) + current_branch = branch_result.stdout.strip() if branch_result.returncode == 0 else "main" + + # Fetch latest from remote without pulling + subprocess.run(["git", "fetch", "origin", current_branch], capture_output=True, cwd=repo_dir) + + result = subprocess.run( + ["git", "rev-parse", f"origin/{current_branch}"], + capture_output=True, + text=True, + cwd=repo_dir + ) if result.returncode == 0: return result.stdout.strip() else: From c1975c0a0b87aad3476528f1aa72a5c2eb76c72e Mon Sep 17 00:00:00 2001 From: Jacktheguy Date: Sun, 26 Apr 2026 21:01:30 -0400 Subject: [PATCH 10/13] fuck --- Dockerfile | 4 +++- core/discord_bot.py | 36 ++++++++++++------------------------ 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/Dockerfile b/Dockerfile index 96e8d0b..3257b0a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,11 @@ FROM nikolaik/python-nodejs:python3.13-nodejs25 -# Store git commit hash +# Store git commit hash and branch ARG GIT_SHA +ARG GIT_BRANCH=main ENV GIT_SHA=$GIT_SHA +ENV GIT_BRANCH=$GIT_BRANCH # Set the working directory in the container diff --git a/core/discord_bot.py b/core/discord_bot.py index f883eeb..ccf8982 100644 --- a/core/discord_bot.py +++ b/core/discord_bot.py @@ -36,34 +36,22 @@ def slash_mention_repl(match): return f"/{match.group(1)}" def get_latest_commit_sha() -> str: - """Fetch the latest commit SHA from GitHub on the current branch""" + """Fetch the latest commit SHA from GitHub using the API""" try: - import subprocess - repo_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + import urllib.request + import json - # Get current branch name - branch_result = subprocess.run( - ["git", "rev-parse", "--abbrev-ref", "HEAD"], - capture_output=True, - text=True, - cwd=repo_dir - ) - current_branch = branch_result.stdout.strip() if branch_result.returncode == 0 else "main" + # Get branch from environment variable (set during Docker build) + current_branch = os.getenv("GIT_BRANCH", "main") - # Fetch latest from remote without pulling - subprocess.run(["git", "fetch", "origin", current_branch], capture_output=True, cwd=repo_dir) + # Use GitHub API to get latest commit + url = f"https://api.github.com/repos/SkyKings-Network/GuildBridgeBot/commits/{current_branch}" - result = subprocess.run( - ["git", "rev-parse", f"origin/{current_branch}"], - capture_output=True, - text=True, - cwd=repo_dir - ) - if result.returncode == 0: - return result.stdout.strip() - else: - print(f"{Color.CYAN}Discord{Color.RESET} > Failed to get latest git SHA: {result.stderr}") - return "unknown" + req = urllib.request.Request(url, headers={'Accept': 'application/vnd.github.v3+json'}) + with urllib.request.urlopen(req, timeout=5) as response: + data = json.loads(response.read().decode()) + return data['sha'] + except Exception as e: print(f"{Color.CYAN}Discord{Color.RESET} > Failed to get latest git SHA: {e}") return "unknown" From 1b8fa6a5cdbb2dd47a1172f19b64c5e654291a0a Mon Sep 17 00:00:00 2001 From: Jacktheguy Date: Sun, 26 Apr 2026 21:13:35 -0400 Subject: [PATCH 11/13] Add GIT_BRANCH as a build argument in Docker workflow --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aa9da9c..915a269 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -53,6 +53,7 @@ jobs: platforms: ${{ matrix.platform }} build-args: | GIT_SHA=${{ github.sha }} + GIT_BRANCH=${{ github.ref_name }} labels: ${{ steps.meta.outputs.labels }} tags: ${{ env.REGISTRY_IMAGE }} outputs: type=image,push-by-digest=true,name-canonical=true,push=true From 0deffe16d0ce3655673d67394bea46e1fdba08cf Mon Sep 17 00:00:00 2001 From: Jacktheguy Date: Sun, 26 Apr 2026 21:22:05 -0400 Subject: [PATCH 12/13] Remove commented code for fetching branch from environment variable in get_latest_commit_sha function --- core/discord_bot.py | 1 - 1 file changed, 1 deletion(-) diff --git a/core/discord_bot.py b/core/discord_bot.py index ccf8982..8d425d5 100644 --- a/core/discord_bot.py +++ b/core/discord_bot.py @@ -41,7 +41,6 @@ def get_latest_commit_sha() -> str: import urllib.request import json - # Get branch from environment variable (set during Docker build) current_branch = os.getenv("GIT_BRANCH", "main") # Use GitHub API to get latest commit From 6d21ec7d0e05471111cb461fdb8c5974c87f79ec Mon Sep 17 00:00:00 2001 From: plun1331 Date: Sun, 26 Apr 2026 18:33:24 -0700 Subject: [PATCH 13/13] Convert get_latest_commit_sha and is_outdated to async --- core/discord_bot.py | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/core/discord_bot.py b/core/discord_bot.py index 8d425d5..5765fcf 100644 --- a/core/discord_bot.py +++ b/core/discord_bot.py @@ -35,30 +35,24 @@ def emoji_repl(match): def slash_mention_repl(match): return f"/{match.group(1)}" -def get_latest_commit_sha() -> str: +async def get_latest_commit_sha() -> str: """Fetch the latest commit SHA from GitHub using the API""" try: - import urllib.request - import json - current_branch = os.getenv("GIT_BRANCH", "main") - - # Use GitHub API to get latest commit - url = f"https://api.github.com/repos/SkyKings-Network/GuildBridgeBot/commits/{current_branch}" - - req = urllib.request.Request(url, headers={'Accept': 'application/vnd.github.v3+json'}) - with urllib.request.urlopen(req, timeout=5) as response: - data = json.loads(response.read().decode()) - return data['sha'] - + async with aiohttp.ClientSession() as sesh: + # Use GitHub API to get latest commit + url = f"https://api.github.com/repos/SkyKings-Network/GuildBridgeBot/commits/{current_branch}" + async with sesh.get(url, headers={'Accept': 'application/vnd.github.v3+json'}) as resp: + data = await resp.json() + return data['sha'] except Exception as e: print(f"{Color.CYAN}Discord{Color.RESET} > Failed to get latest git SHA: {e}") return "unknown" -def is_outdated() -> bool: +async def is_outdated() -> bool: print(f"{Color.CYAN}Discord{Color.RESET} > Checking for updates...") current_sha = os.getenv("GIT_SHA", "unknown") - latest_sha = get_latest_commit_sha() + latest_sha = await get_latest_commit_sha() print(f"{Color.CYAN}Discord{Color.RESET} > Current SHA: {current_sha}") print(f"{Color.CYAN}Discord{Color.RESET} > Latest SHA: {latest_sha}") if current_sha == "unknown" or latest_sha == "unknown": @@ -259,7 +253,7 @@ async def _send_message(self, *args, **kwargs) -> Union[discord.Message, discord ) return None - is_bot_outdated = is_outdated() + is_bot_outdated = await is_outdated() # Add a footer to the embed if the bot is outdated if is_bot_outdated: footer_text = "📩 Bridge Update available!"