Skip to content

Update - #268

Merged
MrIbrahem merged 8 commits into
mainfrom
update
Jul 22, 2026
Merged

Update#268
MrIbrahem merged 8 commits into
mainfrom
update

Conversation

@MrIbrahem

@MrIbrahem MrIbrahem commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Added automated deployment for application code and scheduled tool jobs.
    • Added deployment scripts supporting safe updates, backups, permissions, and optional Python compilation.
    • Added optional colored console logging and separate error log output.
    • Added environment-file configuration support.
  • Bug Fixes

    • Improved script execution isolation and restoration of runtime state.
    • Improved data-copy handling and QID/sitelink processing consistency.
  • Chores

    • Removed obsolete issue and documentation automation templates.
    • Added required logging and configuration packages.

Introduce a new GitHub Actions workflow (.github/workflows/deploy.yml) to copy the repo to Toolforge, fix CRLF on shell scripts, run stage-1 (tool core update) and stage-2 (deploy YAML jobs + cleanup). Add Toolforge deployment scripts: toolforge/deploy_pybot_repo.sh, toolforge/deploy_tools.sh, and toolforge/deploy_scripts/{deploy_from_local.sh,update_pybot_local.sh} to handle copy, archive, optional compile, and tfj job loading. Move previous deploy-new.yml to .github/workflows/old_scripts/deploy.yml and remove the Snorkell documentation workflow and the Sweep issue template.
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The pull request adds a GitHub Actions deployment pipeline and Toolforge deployment scripts, refactors logging and Python script execution, updates scheduled jobs, and changes several data-processing helpers.

Changes

Deployment automation

Layer / File(s) Summary
Deployment script chain
toolforge/deploy_pybot_repo.sh, toolforge/deploy_scripts/*, toolforge/deploy_tools.sh
Adds repository-copy, local deployment, optional compilation, archival, permission handling, and Toolforge job deployment scripts.
Workflow wiring and cleanup
.github/workflows/deploy.yml, .github/workflows/old_scripts/deploy.yml, .github/ISSUE_TEMPLATE/sweep-template.yml, .github/workflows/snorkell-auto-documentation.yml
Adds the main deployment workflow, removes an empty success command from the older workflow, and removes the Sweep Issue and Snorkell workflows.
Scheduled job definitions
toolforge/old_mdwiki-jobs.yaml
Adds hourly sql-new and six-minute French sql-fr jobs.Runtime updates
--- ---
Logging configuration and bootstrap
toolforge/c9/logger_config.py, toolforge/c9/requirements.txt, toolforge/c9/user_conf.py
Adds optional colorized logging, separate error files, watched handlers, dotenv dependencies, and updated bootstrap formatting.
Python script runner and argument handling
toolforge/c9/pwb.py
Isolates script execution in a temporary __main__ module, restores module state, changes argument parsing, and improves warning locations and path handling.Data-processing updates
--- ---
Per-QID accumulation
src/td_core/copy_data/by_qid/sitelinks.py, src/td_core/mdpages/cashwd.py
Builds QID data in temporary structures before storing completed results.
Helper behavior and data isolation
src/md_core/p11143_bot/wd_helps.py, src/md_core_helps/one_time/prior/add_old.py, src/md_core_helps/one_time/wikiblame/bot.py, toolforge/user-config.py
Adds a return annotation, deep-copies transformation data, changes link extraction, and updates configuration quoting.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GitHubActions
  participant Server
  participant deploy_pybot_repo
  participant deploy_tools
  GitHubActions->>Server: SCP repository to temporary path
  GitHubActions->>deploy_pybot_repo: run Stage 1 deployment
  deploy_pybot_repo->>Server: update pybot files
  GitHubActions->>deploy_tools: run Stage 2 job deployment
  deploy_tools->>Server: flush and load changed jobs
  GitHubActions->>Server: remove temporary repository
Loading

Possibly related PRs

Poem

A rabbit hops through scripts tonight,
Deploying code by moonbeam light.
Logs wear colors, jobs gently run,
Deep copies keep originals one.
“Squeak!” says the burrow, “the update is done!”

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is too generic and does not convey the main change in this pull request. Use a concise, specific title that summarizes the primary change, such as the new deployment workflow or script updates.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch update

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@MrIbrahem
MrIbrahem merged commit 7a01683 into main Jul 22, 2026
1 of 2 checks passed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
toolforge/c9/logger_config.py (1)

57-69: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Return type contract broken for non-string input.

format_colored_text is annotated -> str, but the new early return at Line 68 returns textm unchanged whenever it isn't a str. Any caller relying on the declared str return (e.g. concatenation, .format()) can now receive an arbitrary object and fail at runtime. Also, str | Any in the parameter annotation is redundant (Any already subsumes str).

🐛 Proposed fix
-def format_colored_text(textm: str | Any) -> str:
+def format_colored_text(textm: Any) -> str | Any:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@toolforge/c9/logger_config.py` around lines 57 - 69, Update
format_colored_text to always return a string for non-string inputs by
converting textm with the standard string conversion before returning; also
simplify its parameter annotation by removing the redundant str union with Any.
🧹 Nitpick comments (1)
toolforge/c9/user_conf.py (1)

7-10: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Narrow the exception type caught around load_dotenv().

Static analysis flags this blind except Exception. Since this executes before logging is configured, print as a fallback is reasonable, but catching the broadest exception type can mask unrelated failures (e.g. MemoryError, KeyboardInterrupt via BaseException subclasses aside). Consider narrowing to the exceptions load_dotenv/file I/O can actually raise (e.g. OSError).

As flagged by Ruff: "Do not catch blind exception: Exception" (BLE001).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@toolforge/c9/user_conf.py` around lines 7 - 10, Update the exception handler
around load_dotenv() to catch the narrowest expected file-loading exception,
such as OSError, while preserving the existing print(e) fallback.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/md_core_helps/one_time/wikiblame/bot.py`:
- Line 86: Update the parsing logic around results so BeautifulSoup’s find_all
is invoked on the BeautifulSoup element rather than the string variable text.
Preserve the existing anchor-result parsing behavior while ensuring pages with
results no longer raise AttributeError.

In `@toolforge/deploy_pybot_repo.sh`:
- Line 17: Ensure nested deployment commands propagate failures instead of
masking them with a later successful command: update
toolforge/deploy_pybot_repo.sh line 17 to chain the copy, permission, and
update_pybot_local.sh commands with && or invoke the inner shell with sh -euc;
apply the same failure propagation to the cp, tfj flush, and tfj load commands
at toolforge/deploy_tools.sh line 36.

In `@toolforge/deploy_scripts/deploy_from_local.sh`:
- Around line 7-10: Validate positional arguments safely under set -u by
initializing the variables with default-empty expansions before dereferencing
them: update REPO_TMP_DIR and TARGET_DIR in
toolforge/deploy_scripts/deploy_from_local.sh (lines 7-10), and FULL_PATH in
toolforge/deploy_pybot_repo.sh (lines 6-8). Preserve the existing usage-message
validation after these safe initializations.
- Line 106: Update the deployment permission logic around the find/chmod command
to stop applying 770 to every file. Set directory permissions separately, then
apply executable permissions only to the required deployment scripts, leaving
configs, JSON, and other non-executable files without group write/execute
access.

In `@toolforge/deploy_scripts/update_pybot_local.sh`:
- Line 14: Update the CLEAN_INSTALL configuration used by deploy_from_local.sh
from 0 to enable clean installs, ensuring destination-only files removed or
renamed from src are deleted during deployment.
- Line 30: Quote the script path in the deploy invocation so the HOME-derived
path is passed as a single argument and remains safe when it contains spaces or
glob characters. Update the command invoking deploy_from_local.sh while
preserving its existing arguments.

In `@toolforge/deploy_tools.sh`:
- Around line 19-25: Update the filename construction in deploy_tools.sh so it
matches the deployment contract and supplied toolforge/old_mdwiki-jobs.yaml
file, using the expected old_mdwiki-jobs.yaml name. Modify the existence check
around FULL_FILE_PATH to exit with a nonzero status when the expected
configuration file is absent instead of silently succeeding.

---

Outside diff comments:
In `@toolforge/c9/logger_config.py`:
- Around line 57-69: Update format_colored_text to always return a string for
non-string inputs by converting textm with the standard string conversion before
returning; also simplify its parameter annotation by removing the redundant str
union with Any.

---

Nitpick comments:
In `@toolforge/c9/user_conf.py`:
- Around line 7-10: Update the exception handler around load_dotenv() to catch
the narrowest expected file-loading exception, such as OSError, while preserving
the existing print(e) fallback.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8f7a8e6b-d935-4a43-bda5-b7c67357c4d7

📥 Commits

Reviewing files that changed from the base of the PR and between 3436dde and 2b0be2e.

📒 Files selected for processing (19)
  • .github/ISSUE_TEMPLATE/sweep-template.yml
  • .github/workflows/deploy.yml
  • .github/workflows/old_scripts/deploy.yml
  • .github/workflows/snorkell-auto-documentation.yml
  • src/md_core/p11143_bot/wd_helps.py
  • src/md_core_helps/one_time/prior/add_old.py
  • src/md_core_helps/one_time/wikiblame/bot.py
  • src/td_core/copy_data/by_qid/sitelinks.py
  • src/td_core/mdpages/cashwd.py
  • toolforge/c9/logger_config.py
  • toolforge/c9/pwb.py
  • toolforge/c9/requirements.txt
  • toolforge/c9/user_conf.py
  • toolforge/deploy_pybot_repo.sh
  • toolforge/deploy_scripts/deploy_from_local.sh
  • toolforge/deploy_scripts/update_pybot_local.sh
  • toolforge/deploy_tools.sh
  • toolforge/old_mdwiki-jobs.yaml
  • toolforge/user-config.py
💤 Files with no reviewable changes (2)
  • .github/ISSUE_TEMPLATE/sweep-template.yml
  • .github/workflows/snorkell-auto-documentation.yml

self.in_first = True
# ---
results = results_div.find_all("a")
results = text.find_all("a")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Call find_all() on the BeautifulSoup element, not its text.

Line [86] invokes find_all on text, which is a str from line [81]. This raises AttributeError for every page with results and prevents parsing entirely.

Proposed fix
-        results = text.find_all("a")
+        results = results_div.find_all("a")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
results = text.find_all("a")
results = results_div.find_all("a")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/md_core_helps/one_time/wikiblame/bot.py` at line 86, Update the parsing
logic around results so BeautifulSoup’s find_all is invoked on the BeautifulSoup
element rather than the string variable text. Preserve the existing
anchor-result parsing behavior while ensuring pages with results no longer raise
AttributeError.

echo ">>> FULL_PATH: $FULL_PATH"

# Run deployment steps inside mdwiki's toolforge context
become mdwiki sh -c "cp -rf \"$FULL_PATH/toolforge/deploy_scripts\" /data/project/mdwiki -v;chmod +x /data/project/mdwiki/deploy_scripts/*.sh -v;/data/project/mdwiki/deploy_scripts/update_pybot_local.sh \"$FULL_PATH\""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Propagate failures from nested deployment shells.

The parent shell’s set -e does not make sh -c fail fast. With semicolon-separated commands, an earlier copy, flush, or permission failure can be followed by a successful final command, causing deployment to report success incorrectly.

  • toolforge/deploy_pybot_repo.sh#L17-L17: use && or invoke the inner shell with sh -euc.
  • toolforge/deploy_tools.sh#L36-L36: apply the same failure propagation to cp, tfj flush, and tfj load.
📍 Affects 2 files
  • toolforge/deploy_pybot_repo.sh#L17-L17 (this comment)
  • toolforge/deploy_tools.sh#L36-L36
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@toolforge/deploy_pybot_repo.sh` at line 17, Ensure nested deployment commands
propagate failures instead of masking them with a later successful command:
update toolforge/deploy_pybot_repo.sh line 17 to chain the copy, permission, and
update_pybot_local.sh commands with && or invoke the inner shell with sh -euc;
apply the same failure propagation to the cp, tfj flush, and tfj load commands
at toolforge/deploy_tools.sh line 36.

Comment on lines +7 to +10
REPO_TMP_DIR="$1" # Path to uploaded tmp folder, e.g., /home/username/arwiki_repo_tmp
TARGET_DIR="$2" # Target tool folder, e.g., ARWIKI_ONE_REPO

if [ -z "${1:-}" ] || [ -z "${2:-}" ]; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Validate positional arguments before dereferencing them under set -u.

Both scripts currently terminate with an unbound-variable error before their intended usage message can run.

  • toolforge/deploy_scripts/deploy_from_local.sh#L7-L10: initialize arguments with ${1:-} and ${2:-} before validation.
  • toolforge/deploy_pybot_repo.sh#L6-L8: initialize FULL_PATH with ${1:-} before validation.
📍 Affects 2 files
  • toolforge/deploy_scripts/deploy_from_local.sh#L7-L10 (this comment)
  • toolforge/deploy_pybot_repo.sh#L6-L8
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@toolforge/deploy_scripts/deploy_from_local.sh` around lines 7 - 10, Validate
positional arguments safely under set -u by initializing the variables with
default-empty expansions before dereferencing them: update REPO_TMP_DIR and
TARGET_DIR in toolforge/deploy_scripts/deploy_from_local.sh (lines 7-10), and
FULL_PATH in toolforge/deploy_pybot_repo.sh (lines 6-8). Preserve the existing
usage-message validation after these safe initializations.

# Optional: Set permissions
# chmod -R 770 "$TARGET_DIR"

find "$TARGET_DIR" -type f ! -name "*.pyc" -exec chmod 770 {} \;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '1,180p' toolforge/deploy_scripts/deploy_from_local.sh | cat -n

Repository: Mdwiki-TD/mdwiki-python-files

Length of output: 4313


🏁 Script executed:

printf '%s\n' "need tool output"

Repository: Mdwiki-TD/mdwiki-python-files

Length of output: 184


🏁 Script executed:

rg -n "chmod|find .*type" toolforge/deploy_scripts/deploy_from_local.sh

Repository: Mdwiki-TD/mdwiki-python-files

Length of output: 408


🏁 Script executed:

sed -n '80,130p' toolforge/deploy_scripts/deploy_from_local.sh | cat -n

Repository: Mdwiki-TD/mdwiki-python-files

Length of output: 1361


Avoid chmod 770 on every deployed file

find "$TARGET_DIR" -type f ! -name "*.pyc" -exec chmod 770 {} \; gives group write/execute to configs, JSON, and other non-executable files. Set directory perms separately and only mark the scripts that need it as executable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@toolforge/deploy_scripts/deploy_from_local.sh` at line 106, Update the
deployment permission logic around the find/chmod command to stop applying 770
to every file. Set directory permissions separately, then apply executable
permissions only to the required deployment scripts, leaving configs, JSON, and
other non-executable files without group write/execute access.

fi

export SUB_DIR_COPY="src"
export CLEAN_INSTALL=0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Prevent stale files from surviving deployments.

With CLEAN_INSTALL=0, deploy_from_local.sh overlays the source onto pybot but never removes files deleted or renamed in src. Old modules can remain importable and execute in production. Enable clean installs or use a mirror operation that removes destination-only files.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@toolforge/deploy_scripts/update_pybot_local.sh` at line 14, Update the
CLEAN_INSTALL configuration used by deploy_from_local.sh from 0 to enable clean
installs, ensuring destination-only files removed or renamed from src are
deleted during deployment.


# Execute the local deployment script directly without cloning from GitHub
# We copy the script to ~/deploy_scripts/ first from the github action workflow, then call it
$HOME/deploy_scripts/deploy_from_local.sh "$REPO_TMP_DIR" "$TARGET_DIR"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the file and inspect the relevant lines.
git ls-files toolforge/deploy_scripts/update_pybot_local.sh
wc -l toolforge/deploy_scripts/update_pybot_local.sh
cat -n toolforge/deploy_scripts/update_pybot_local.sh | sed -n '1,120p'

# Look for any related script references that might show intended quoting style.
rg -n '\$HOME/deploy_scripts/deploy_from_local\.sh|deploy_from_local\.sh' toolforge -S

Repository: Mdwiki-TD/mdwiki-python-files

Length of output: 1448


Quote the script path. $HOME/deploy_scripts/deploy_from_local.sh should be "$HOME/deploy_scripts/deploy_from_local.sh" so HOME values with spaces or glob characters don’t break the invocation.

🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 30-30: Double quote to prevent globbing and word splitting.

(SC2086)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@toolforge/deploy_scripts/update_pybot_local.sh` at line 30, Quote the script
path in the deploy invocation so the HOME-derived path is passed as a single
argument and remains safe when it contains spaces or glob characters. Update the
command invoking deploy_from_local.sh while preserving its existing arguments.

Source: Linters/SAST tools

Comment thread toolforge/deploy_tools.sh
Comment on lines +19 to +25
filename="${tool}-jobs.yaml"
FULL_FILE_PATH="${SOURCE_PATH}/$filename"

echo "Checking for configuration file: $filename"

# Check if the file actually exists before proceeding
if [ -f "$FULL_FILE_PATH" ]; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make the job filename match the deployment contract.

The workflow passes FULL_PATH/toolforge, but this script searches for mdwiki-jobs.yaml while the supplied file is toolforge/old_mdwiki-jobs.yaml. The condition is therefore skipped and the script exits successfully without loading the new jobs. Rename the file or update the expected filename, and fail when the expected file is absent.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@toolforge/deploy_tools.sh` around lines 19 - 25, Update the filename
construction in deploy_tools.sh so it matches the deployment contract and
supplied toolforge/old_mdwiki-jobs.yaml file, using the expected
old_mdwiki-jobs.yaml name. Modify the existence check around FULL_FILE_PATH to
exit with a nonzero status when the expected configuration file is absent
instead of silently succeeding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant