From ebb28d8a5a97450f438caf99b1c955d2353e148c Mon Sep 17 00:00:00 2001 From: Airah Yusuff Date: Fri, 26 Sep 2025 18:20:03 +0100 Subject: [PATCH 01/10] script to update mentors.yml with monthly ad-hoc availability --- .../automation_prepare_adhoc_availability.py | 133 ++++++++++++++++++ tools/run_adhoc_prep_automation.sh | 13 ++ tools/samples/adhoc-prep.xlsx | Bin 0 -> 9629 bytes 3 files changed, 146 insertions(+) create mode 100644 tools/automation_prepare_adhoc_availability.py create mode 100644 tools/run_adhoc_prep_automation.sh create mode 100644 tools/samples/adhoc-prep.xlsx diff --git a/tools/automation_prepare_adhoc_availability.py b/tools/automation_prepare_adhoc_availability.py new file mode 100644 index 00000000..d01ba803 --- /dev/null +++ b/tools/automation_prepare_adhoc_availability.py @@ -0,0 +1,133 @@ +""" + Create a script that will update availability and hours for mentors in preparation for adhoc registration for a specified month +""" +# !/usr/bin/env python + +import logging +import sys +import pandas as pd +from ruamel.yaml import YAML + +yaml = YAML() +yaml.width = 4096 + +TYPE_LONG_TERM = "long-term" +TYPE_AD_HOC = "ad-hoc" +TYPE_BOTH = "both" + +MONTHS_MAP = { + 4: 'April', + 5: 'May', + 6: 'June', + 7: 'July', + 8: 'August', + 9: 'September', + 10: 'October', + 11: 'November' +} + + +def get_available_mentor_sort(mentor, current_availability): + """ + Returns sort value for mentor if: + - mentor is new (availability still contains full list of months), sort to highest: 500 + - mentor has >3 available hours, sort to highest: 500 + - 3 or less hours, sort: 200 + - mentor is long-term only, sort: 10 + + Guide: https://docs.google.com/document/d/1GwlleBNScHCQ3K8rgvYIB3upIr1BylgWjGR2jxwYWtI/edit?tab=t.0 + """ + + if len(current_availability) > 1 or mentor.get('hours') > 3: + return 500 + + return 200 + + +def get_unavailable_mentor_sort(mentor): + """ + Returns sort value for mentor if: + - mentor is ad-hoc only or both but no available hours for the month, sort: 100 + - mentor is long-term only, sort: 10 + """ + if mentor.get("type") == TYPE_LONG_TERM: + return 10 + + return 100 + + +def get_availability_update_dict(available_mentors): + """ + Returns a dictionary mapping mentor to their available hours (from spreadsheet file) + """ + availability_update_dict = {} + + for _, row in available_mentors.iterrows(): + mentor_name = row['Mentor Name'].strip() + updated_hours = row['Availability (Hours)'] + + # if hours column in spreadhseet is empty, existing hours should be kept + if pd.isna(updated_hours) or str(updated_hours).strip() == "": + availability_update_dict[mentor_name] = None + else: + availability_update_dict[mentor_name] = updated_hours + + return availability_update_dict + + +def update_mentor_availability(month, xlsx_file_path, yml_file_path): + df_available_mentors = pd.read_excel(xlsx_file_path) + availability_updates = get_availability_update_dict(df_available_mentors) + + with open(yml_file_path, 'r') as input_yml: + mentors = yaml.load(input_yml) or [] + + for mentor in mentors: + yml_name = mentor['name'].strip() + + if yml_name not in availability_updates: + mentor['sort'] = get_unavailable_mentor_sort(mentor) + mentor['availability'] = [] + continue + + current_availability = mentor.get('availability', []) + logging.info(f"Current availability for {yml_name}: {current_availability}") + + mentor['sort'] = get_available_mentor_sort(mentor, current_availability) + + # reset availability to the current month only + mentor['availability'] = [month] + + # Only update hours if updated hours is None + updated_hours = availability_updates.get(yml_name) + if updated_hours is not None: + mentor['hours'] = availability_updates[yml_name] + + with open(yml_file_path, 'w') as f: + yaml.default_flow_style = True + yaml.dump(mentors, f) + + print(f"Mentor availability updated for month {MONTHS_MAP[month]}.") + + +def run_automation(): + logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + + mentors_yml_file_path = "../_data/mentors.yml" + + if len(sys.argv) == 3: + xlsx_file_path = sys.argv[1] + month = int(sys.argv[2]) + + logging.info("Using values: xlsx: %s, month: %s", xlsx_file_path, month) + else: + xlsx_file_path = "samples/adhoc-prep.xlsx" + month = 11 + + logging.info("Default values: xlsx: %s, month: %s", xlsx_file_path, month) + + update_mentor_availability(month, xlsx_file_path, mentors_yml_file_path) + + +if __name__ == "__main__": + run_automation() diff --git a/tools/run_adhoc_prep_automation.sh b/tools/run_adhoc_prep_automation.sh new file mode 100644 index 00000000..b1f7003b --- /dev/null +++ b/tools/run_adhoc_prep_automation.sh @@ -0,0 +1,13 @@ +#Create the virtual environment On macOS/Linux +python3 -m venv myenv + +#Activate the virtual environment: +source myenv/bin/activate + +# Install packages +pip install -r requirements.txt + +# Enter the parameters: FILE_PATH_XLSX MONTH +# Example: samples/adhoc-prep.xlsx 9 +# month: the adhoc month in number e.g 4 -> April, 11 -> November +python3 automation_prepare_adhoc_availability.py samples/adhoc-prep.xlsx 10 diff --git a/tools/samples/adhoc-prep.xlsx b/tools/samples/adhoc-prep.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..ecc3fbed050cc0728ddbe184bac463bbcdc81d43 GIT binary patch literal 9629 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 Date: Sat, 27 Sep 2025 17:06:18 +0100 Subject: [PATCH 02/10] updates, readmes, minor fixes --- _data/mentors.yml | 4 ++-- tools/README.md | 22 ++++++++++++++++-- .../automation_prepare_adhoc_availability.py | 3 +++ tools/samples/adhoc-prep.xlsx | Bin 9629 -> 9443 bytes 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/_data/mentors.yml b/_data/mentors.yml index 2d290643..c0552d7f 100644 --- a/_data/mentors.yml +++ b/_data/mentors.yml @@ -2824,7 +2824,7 @@ - Grow beyond senior level extra: Focus areas for aspiring data scientists; transitioning into data science, building a roadmap, preparing for technical interviews, optimizing resume/LinkedIn, creating and showcasing portfolio projects, and communicating insights effectively. network: - - linkedin: https://www.linkedin.com/in/ilayda-yilmaz/ + - linkedin: https://www.linkedin.com/in/ilayda-yilmaz/ - name: Damola Taiwo disabled: false @@ -2891,7 +2891,7 @@ - Grow from mid-level to senior-level - Grow from beginner to mid-level - Switch career to IT - extra: + extra: | Data engineering best practices; Data architecture design and implementation; Transitioning from on-premises to cloud solutions (with focus on Databricks); Growing from junior to mid-level; Growing from mid-level to senior-level; Career development and strategic planning in data roles; Technology architecture & strategy; Career growth & soft skills; Navigating the job market and building a professional brand; Effective communication in technical teams diff --git a/tools/README.md b/tools/README.md index 0b6603c5..c1e81263 100644 --- a/tools/README.md +++ b/tools/README.md @@ -5,7 +5,11 @@ There are two automation scripts: 2) `download_image.py`: downloads image from a specified URL and saves in `assets/images/mentors` -3) `automation_create_mentor_spreadsheets.py`: creates spreadhseets for each longterm mentor with filenames like `WCC - Long Term - MentorName.xlsx`. All the files are saved in a folder named `Long Term Mentors`. It uses the data from `Mentorship Programme long-term Registration Form for Mentees (Responses).xlsx` sheetname `Revised Mentees`as input. +3) `meetup_import.py`: imports new upcoming events from the WCC MeetUp page using the iCal feed: https://www.meetup.com/women-coding-community/events/ical/ + +4) `automation_create_mentor_spreadsheets.py`: creates spreadhseets for each longterm mentor with filenames like `WCC - Long Term - MentorName.xlsx`. All the files are saved in a folder named `Long Term Mentors`. It uses the data from `Mentorship Programme long-term Registration Form for Mentees (Responses).xlsx` sheetname `Revised Mentees`as input. + +5) `automation_prepare_adhoc_availability.py`: updates mentors data with specified availability hours in `samples/adhoc-prep.xlsx` in preparation for monthly ad-hoc mentorship. ### Dependencies @@ -75,4 +79,18 @@ sh run_meetup_import.sh 📁 Long Term Mentors │── WCC - Long Term - Nonna Shakhova.xlsx │── WCC - Long Term - Rajani Rao.xlsx - │── WCC - Long Term - Gabriel Oliveira.xlsx └── (more mentor files...) \ No newline at end of file + │── WCC - Long Term - Gabriel Oliveira.xlsx └── (more mentor files...) + +#### E) `automation_prepare_adhoc_availability.py` + +```shell +sh run_adhoc_prep_automation.sh +``` +**Note:** +- Ensure to update `adhoc-prep.xslx` with the new data to be updated for the mentors. +- The GHA workflow for this script uses a Google Cloud service account setup to retrieve the file from Google Drive. The service key has been configured for womencodingcommunity Google Drive account and the file to be used/updated has been shared with the service account email. +Hence, to run the GHA workflow, you only need to provide: + - the month value (e.g 9 for September) and, + - the URL to the excel sheet + +For more information, you can read the [README](blog_automation/README.md) in the blog automation folder. diff --git a/tools/automation_prepare_adhoc_availability.py b/tools/automation_prepare_adhoc_availability.py index d01ba803..d9aeaed0 100644 --- a/tools/automation_prepare_adhoc_availability.py +++ b/tools/automation_prepare_adhoc_availability.py @@ -50,6 +50,9 @@ def get_unavailable_mentor_sort(mentor): - mentor is ad-hoc only or both but no available hours for the month, sort: 100 - mentor is long-term only, sort: 10 """ + if mentor.get("disabled", True): + return 1 + if mentor.get("type") == TYPE_LONG_TERM: return 10 diff --git a/tools/samples/adhoc-prep.xlsx b/tools/samples/adhoc-prep.xlsx index ecc3fbed050cc0728ddbe184bac463bbcdc81d43..15567fe95675be56e8a9ca82a11e8b086168e663 100644 GIT binary patch delta 2799 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 Date: Sat, 27 Sep 2025 17:08:37 +0100 Subject: [PATCH 03/10] add workflow for adhoc-availability[wip to restrict to only parent repo] --- .github/workflows/adhoc_availability_prep.yml | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/adhoc_availability_prep.yml diff --git a/.github/workflows/adhoc_availability_prep.yml b/.github/workflows/adhoc_availability_prep.yml new file mode 100644 index 00000000..7733d985 --- /dev/null +++ b/.github/workflows/adhoc_availability_prep.yml @@ -0,0 +1,67 @@ +name: Update Mentor Availabilities for Monthly Ad-Hoc Prep + +on: + workflow_dispatch: + inputs: + month: + description: "Month number (e.g. 10 for October)" + required: true + file_url: + description: "Google Drive URL of the Excel file with the availabilities (see samples/adhoc-prep.xlsx for the expected columns in the sheet)" + required: true + +jobs: + update-mentors: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Cache pip + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('tools/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r tools/requirements.txt + pip install gdown + + - name: Save Google Drive credentials + run: echo '${{ secrets.GOOGLECLOUD_SERVICE_KEY_RETRIEVE_ADHOC_FILE_JSON }}' > service_account.json + + - name: Download Excel file securely + run: gdown --fuzzy --service-account service_account.json "${{ github.event.inputs.file_url }}" -O tools/adhoc.xlsx + + - name: Run script + run: | + cd tools + python automation_prepare_adhoc_availability.py adhoc.xlsx ${{ github.event.inputs.month }} + + - name: Create or Update Pull Request + uses: peter-evans/create-pull-request@v7 + with: + token: ${{ secrets.GHA_ACTIONS_ALLOW_TOKEN }} + commit-message: "updated mentor hours, availabilities, and sort for monthly adhoc prep" + branch: "automation/adhoc-monthly-prep" + team-reviewers: | + Women-Coding-Community/leaders + title: "[GHA Workflow] Monthly Ad-hoc Prep - Month ${{ github.event.inputs.month }}" + body: | + This PR was created automatically by a GitHub Action that handles mentor data updates for the monthly ad-hoc preparation. + Only `_data/mentors.yml` should be updated. + + Please review the changes `_data/mentors.yml` and ensure that the changes are as expected before merging (Review the availability sheet used). + labels: | + automation + adhoc-prep From d1db4988585592e7368a7c256aaed231e5e00165 Mon Sep 17 00:00:00 2001 From: Airah Yusuff Date: Sat, 27 Sep 2025 17:09:08 +0100 Subject: [PATCH 04/10] update meetup automation to use new generic token, prev to be deleted --- .github/workflows/import_meetup_events.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/import_meetup_events.yml b/.github/workflows/import_meetup_events.yml index 17a96eef..7582037e 100644 --- a/.github/workflows/import_meetup_events.yml +++ b/.github/workflows/import_meetup_events.yml @@ -45,7 +45,7 @@ jobs: - name: Create or Update Pull Request uses: peter-evans/create-pull-request@v7 with: - token: ${{ secrets.MEETUP_IMPORT_ACTIONS_TOKEN }} + token: ${{ secrets.GHA_ACTIONS_ALLOW_TOKEN }} commit-message: "Automated import of Meetup events" branch: "automation/import-meetup-events" team-reviewers: "Women-Coding-Community/leaders" From 3c15969351a74365284e522a1bef886151aaa6cf Mon Sep 17 00:00:00 2001 From: Airah Yusuff Date: Sat, 27 Sep 2025 17:27:15 +0100 Subject: [PATCH 05/10] replace gdown with rclone for retrieving google drive files securely --- .github/workflows/adhoc_availability_prep.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/adhoc_availability_prep.yml b/.github/workflows/adhoc_availability_prep.yml index 7733d985..2fc888b5 100644 --- a/.github/workflows/adhoc_availability_prep.yml +++ b/.github/workflows/adhoc_availability_prep.yml @@ -6,8 +6,8 @@ on: month: description: "Month number (e.g. 10 for October)" required: true - file_url: - description: "Google Drive URL of the Excel file with the availabilities (see samples/adhoc-prep.xlsx for the expected columns in the sheet)" + file_id: + description: "Google Drive file ID of the Excel sheet with the availabilities (see samples/adhoc-prep.xlsx for the expected columns in the sheet)" required: true jobs: @@ -36,12 +36,15 @@ jobs: python -m pip install --upgrade pip pip install -r tools/requirements.txt pip install gdown + sudo apt-get update && sudo apt-get install -y rclone - - name: Save Google Drive credentials - run: echo '${{ secrets.GOOGLECLOUD_SERVICE_KEY_RETRIEVE_ADHOC_FILE_JSON }}' > service_account.json + - name: Configure rclone with Google Cloud service account + run: | + echo "${{ secrets.GOOGLECLOUD_SERVICE_KEY_RETRIEVE_ADHOC_FILE_JSON }}" > service_account.json + rclone config create gdrive drive scope=drive service_account_file=service_account.json - - name: Download Excel file securely - run: gdown --fuzzy --service-account service_account.json "${{ github.event.inputs.file_url }}" -O tools/adhoc.xlsx + - name: Download spreadsheet from Google Drive + run: rclone copy gdrive:${{ github.event.inputs.file_id }} tools/adhoc.xlsx - name: Run script run: | From f6539828df8db446afe9f5582830836dc4396157 Mon Sep 17 00:00:00 2001 From: Airah Yusuff Date: Sat, 27 Sep 2025 17:38:54 +0100 Subject: [PATCH 06/10] use copyid syntax from documentation --- .github/workflows/adhoc_availability_prep.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/adhoc_availability_prep.yml b/.github/workflows/adhoc_availability_prep.yml index 2fc888b5..aa8bb709 100644 --- a/.github/workflows/adhoc_availability_prep.yml +++ b/.github/workflows/adhoc_availability_prep.yml @@ -7,7 +7,7 @@ on: description: "Month number (e.g. 10 for October)" required: true file_id: - description: "Google Drive file ID of the Excel sheet with the availabilities (see samples/adhoc-prep.xlsx for the expected columns in the sheet)" + description: "Google Drive file ID of the Excel sheet with the availabilities" required: true jobs: @@ -35,16 +35,16 @@ jobs: run: | python -m pip install --upgrade pip pip install -r tools/requirements.txt - pip install gdown - sudo apt-get update && sudo apt-get install -y rclone - - name: Configure rclone with Google Cloud service account + - name: Install and Configure rclone with Google Cloud service account run: | - echo "${{ secrets.GOOGLECLOUD_SERVICE_KEY_RETRIEVE_ADHOC_FILE_JSON }}" > service_account.json + curl https://rclone.org/install.sh | sudo bash + echo '${{ secrets.GOOGLECLOUD_SERVICE_KEY_RETRIEVE_ADHOC_FILE_JSON }}' > service_account.json rclone config create gdrive drive scope=drive service_account_file=service_account.json - name: Download spreadsheet from Google Drive - run: rclone copy gdrive:${{ github.event.inputs.file_id }} tools/adhoc.xlsx + run: | + rclone backend copyid gdrive: ${{ github.event.inputs.file_id }} tools/adhoc.xlsx - name: Run script run: | From f070dcef86a0bd08b8dcaf200af667edad826a0d Mon Sep 17 00:00:00 2001 From: Airah Yusuff Date: Sat, 27 Sep 2025 18:23:04 +0100 Subject: [PATCH 07/10] updates --- .github/workflows/adhoc_availability_prep.yml | 5 +++++ tools/README.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/adhoc_availability_prep.yml b/.github/workflows/adhoc_availability_prep.yml index aa8bb709..19079e9b 100644 --- a/.github/workflows/adhoc_availability_prep.yml +++ b/.github/workflows/adhoc_availability_prep.yml @@ -57,6 +57,7 @@ jobs: token: ${{ secrets.GHA_ACTIONS_ALLOW_TOKEN }} commit-message: "updated mentor hours, availabilities, and sort for monthly adhoc prep" branch: "automation/adhoc-monthly-prep" + path: _data/mentors.yml team-reviewers: | Women-Coding-Community/leaders title: "[GHA Workflow] Monthly Ad-hoc Prep - Month ${{ github.event.inputs.month }}" @@ -68,3 +69,7 @@ jobs: labels: | automation adhoc-prep + + - name: Cleanup files + if: always() + run: rm -f service_account.json tools/adhoc.xlsx diff --git a/tools/README.md b/tools/README.md index c1e81263..94b5c3dc 100644 --- a/tools/README.md +++ b/tools/README.md @@ -91,6 +91,6 @@ sh run_adhoc_prep_automation.sh - The GHA workflow for this script uses a Google Cloud service account setup to retrieve the file from Google Drive. The service key has been configured for womencodingcommunity Google Drive account and the file to be used/updated has been shared with the service account email. Hence, to run the GHA workflow, you only need to provide: - the month value (e.g 9 for September) and, - - the URL to the excel sheet + - the file ID for the excel sheet to use For more information, you can read the [README](blog_automation/README.md) in the blog automation folder. From 67e45d514b0cafb651811f1839f4b2e0e7867a0e Mon Sep 17 00:00:00 2001 From: Airah Yusuff Date: Sat, 27 Sep 2025 18:28:26 +0100 Subject: [PATCH 08/10] updates --- .github/workflows/adhoc_availability_prep.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/adhoc_availability_prep.yml b/.github/workflows/adhoc_availability_prep.yml index 19079e9b..86a2d6db 100644 --- a/.github/workflows/adhoc_availability_prep.yml +++ b/.github/workflows/adhoc_availability_prep.yml @@ -51,13 +51,16 @@ jobs: cd tools python automation_prepare_adhoc_availability.py adhoc.xlsx ${{ github.event.inputs.month }} + - name: Cleanup files + if: always() + run: rm -f service_account.json tools/adhoc.xlsx + - name: Create or Update Pull Request uses: peter-evans/create-pull-request@v7 with: token: ${{ secrets.GHA_ACTIONS_ALLOW_TOKEN }} commit-message: "updated mentor hours, availabilities, and sort for monthly adhoc prep" branch: "automation/adhoc-monthly-prep" - path: _data/mentors.yml team-reviewers: | Women-Coding-Community/leaders title: "[GHA Workflow] Monthly Ad-hoc Prep - Month ${{ github.event.inputs.month }}" @@ -69,7 +72,3 @@ jobs: labels: | automation adhoc-prep - - - name: Cleanup files - if: always() - run: rm -f service_account.json tools/adhoc.xlsx From 45fc84a0e8deaca0038b854df68e306d813f7894 Mon Sep 17 00:00:00 2001 From: Airah Yusuff Date: Sat, 27 Sep 2025 19:00:44 +0100 Subject: [PATCH 09/10] documentation updates --- tools/README.md | 6 +++--- tools/automation_prepare_adhoc_availability.py | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tools/README.md b/tools/README.md index 94b5c3dc..c3d83541 100644 --- a/tools/README.md +++ b/tools/README.md @@ -87,10 +87,10 @@ sh run_meetup_import.sh sh run_adhoc_prep_automation.sh ``` **Note:** -- Ensure to update `adhoc-prep.xslx` with the new data to be updated for the mentors. -- The GHA workflow for this script uses a Google Cloud service account setup to retrieve the file from Google Drive. The service key has been configured for womencodingcommunity Google Drive account and the file to be used/updated has been shared with the service account email. +- If running locally, ensure to update `adhoc-prep.xslx` with the new data to be updated for the mentors. +- If using GitHub Actions, the GHA workflow for this script uses a Google Cloud service account setup to retrieve the file from Google Drive. The service key has been configured for womencodingcommunity Google Drive account and the file to be used/updated has been shared with the service account email. Hence, to run the GHA workflow, you only need to provide: - the month value (e.g 9 for September) and, - the file ID for the excel sheet to use -For more information, you can read the [README](blog_automation/README.md) in the blog automation folder. +For more information on the GC service account configurations, you can read the [README](blog_automation/README.md) in the blog automation folder. diff --git a/tools/automation_prepare_adhoc_availability.py b/tools/automation_prepare_adhoc_availability.py index d9aeaed0..2a349ab9 100644 --- a/tools/automation_prepare_adhoc_availability.py +++ b/tools/automation_prepare_adhoc_availability.py @@ -33,7 +33,6 @@ def get_available_mentor_sort(mentor, current_availability): - mentor is new (availability still contains full list of months), sort to highest: 500 - mentor has >3 available hours, sort to highest: 500 - 3 or less hours, sort: 200 - - mentor is long-term only, sort: 10 Guide: https://docs.google.com/document/d/1GwlleBNScHCQ3K8rgvYIB3upIr1BylgWjGR2jxwYWtI/edit?tab=t.0 """ @@ -49,6 +48,7 @@ def get_unavailable_mentor_sort(mentor): Returns sort value for mentor if: - mentor is ad-hoc only or both but no available hours for the month, sort: 100 - mentor is long-term only, sort: 10 + - mentor is deactivated, sort: 1 """ if mentor.get("disabled", True): return 1 @@ -104,13 +104,14 @@ def update_mentor_availability(month, xlsx_file_path, yml_file_path): # Only update hours if updated hours is None updated_hours = availability_updates.get(yml_name) if updated_hours is not None: - mentor['hours'] = availability_updates[yml_name] + logging.info(f"Updating hours for {yml_name} to: {updated_hours}") + mentor['hours'] = updated_hours with open(yml_file_path, 'w') as f: yaml.default_flow_style = True yaml.dump(mentors, f) - print(f"Mentor availability updated for month {MONTHS_MAP[month]}.") + print(f"Mentor availabilities updated for month {MONTHS_MAP[month]}.") def run_automation(): From 5478240bbe69ea39205b3a229f76960f1499caa6 Mon Sep 17 00:00:00 2001 From: Airah Yusuff Date: Sun, 28 Sep 2025 07:43:07 +0100 Subject: [PATCH 10/10] updates + doc comments for clarity --- .github/workflows/adhoc_availability_prep.yml | 2 +- .../automation_prepare_adhoc_availability.py | 25 ++++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/.github/workflows/adhoc_availability_prep.yml b/.github/workflows/adhoc_availability_prep.yml index 86a2d6db..ae6660c1 100644 --- a/.github/workflows/adhoc_availability_prep.yml +++ b/.github/workflows/adhoc_availability_prep.yml @@ -63,7 +63,7 @@ jobs: branch: "automation/adhoc-monthly-prep" team-reviewers: | Women-Coding-Community/leaders - title: "[GHA Workflow] Monthly Ad-hoc Prep - Month ${{ github.event.inputs.month }}" + title: "[WCC Bot] Monthly Ad-hoc Prep - Month ${{ github.event.inputs.month }}" body: | This PR was created automatically by a GitHub Action that handles mentor data updates for the monthly ad-hoc preparation. Only `_data/mentors.yml` should be updated. diff --git a/tools/automation_prepare_adhoc_availability.py b/tools/automation_prepare_adhoc_availability.py index 2a349ab9..b565db3b 100644 --- a/tools/automation_prepare_adhoc_availability.py +++ b/tools/automation_prepare_adhoc_availability.py @@ -29,11 +29,13 @@ def get_available_mentor_sort(mentor, current_availability): """ - Returns sort value for mentor if: - - mentor is new (availability still contains full list of months), sort to highest: 500 + Returns sort value for available mentors ONLY if: + - mentor is new (current availability still contains full list of months), sort to highest: 500 - mentor has >3 available hours, sort to highest: 500 - 3 or less hours, sort: 200 + Note: sort logic for unavailable mentors is split on purpose (see update_mentor_availability function) + Guide: https://docs.google.com/document/d/1GwlleBNScHCQ3K8rgvYIB3upIr1BylgWjGR2jxwYWtI/edit?tab=t.0 """ @@ -45,7 +47,7 @@ def get_available_mentor_sort(mentor, current_availability): def get_unavailable_mentor_sort(mentor): """ - Returns sort value for mentor if: + Returns sort value for unavailable mentor if: - mentor is ad-hoc only or both but no available hours for the month, sort: 100 - mentor is long-term only, sort: 10 - mentor is deactivated, sort: 1 @@ -62,6 +64,7 @@ def get_unavailable_mentor_sort(mentor): def get_availability_update_dict(available_mentors): """ Returns a dictionary mapping mentor to their available hours (from spreadsheet file) + - If hours column in spreadsheet is empty/non-numeric, the value will be None (indicating existing hours should be kept) """ availability_update_dict = {} @@ -69,7 +72,6 @@ def get_availability_update_dict(available_mentors): mentor_name = row['Mentor Name'].strip() updated_hours = row['Availability (Hours)'] - # if hours column in spreadhseet is empty, existing hours should be kept if pd.isna(updated_hours) or str(updated_hours).strip() == "": availability_update_dict[mentor_name] = None else: @@ -79,6 +81,13 @@ def get_availability_update_dict(available_mentors): def update_mentor_availability(month, xlsx_file_path, yml_file_path): + """ + Updates mentor availability and hours in the mentors.yml file based on the provided xlsx file for a given month. + - Mentors not listed in the xlsx file are set to unavailable for the month. + - Mentors listed in the xlsx file have their availability set to the specified month and hours updated if provided. + - All mentors are re-sorted according to the guide: https://docs.google.com/document/d/1GwlleBNScHCQ3K8rgvYIB3upIr1BylgWjGR2jxwYWtI/edit?tab=t.0 + """ + df_available_mentors = pd.read_excel(xlsx_file_path) availability_updates = get_availability_update_dict(df_available_mentors) @@ -88,20 +97,18 @@ def update_mentor_availability(month, xlsx_file_path, yml_file_path): for mentor in mentors: yml_name = mentor['name'].strip() + # if mentor is not included in availability file: update sort, set availability to none, and move to next mentor if yml_name not in availability_updates: mentor['sort'] = get_unavailable_mentor_sort(mentor) mentor['availability'] = [] continue + # otherwise: mentor is available, update sort and reset availability to the current month only current_availability = mentor.get('availability', []) - logging.info(f"Current availability for {yml_name}: {current_availability}") - mentor['sort'] = get_available_mentor_sort(mentor, current_availability) - - # reset availability to the current month only mentor['availability'] = [month] - # Only update hours if updated hours is None + # Only update hours if updated hours is not None updated_hours = availability_updates.get(yml_name) if updated_hours is not None: logging.info(f"Updating hours for {yml_name} to: {updated_hours}")