-
Notifications
You must be signed in to change notification settings - Fork 50
Add Automation workflow for updating mentor for ad-hoc monthly prep #575
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
khairahscorner
merged 12 commits into
Women-Coding-Community:main
from
khairahscorner:adhoc-availability-script
Sep 28, 2025
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
ebb28d8
script to update mentors.yml with monthly ad-hoc availability
khairahscorner 3d67395
Merge branch 'main' of https://github.com/Women-Coding-Community/Wome…
khairahscorner dd5f456
Merge branch 'main' of https://github.com/Women-Coding-Community/Wome…
khairahscorner a641623
updates, readmes, minor fixes
khairahscorner 2d02909
add workflow for adhoc-availability[wip to restrict to only parent repo]
khairahscorner d1db498
update meetup automation to use new generic token, prev to be deleted
khairahscorner 3c15969
replace gdown with rclone for retrieving google drive files securely
khairahscorner f653982
use copyid syntax from documentation
khairahscorner f070dce
updates
khairahscorner 67e45d5
updates
khairahscorner 45fc84a
documentation updates
khairahscorner 5478240
updates + doc comments for clarity
khairahscorner File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| 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_id: | ||
| description: "Google Drive file ID of the Excel sheet with the availabilities" | ||
| 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 | ||
|
|
||
| - name: Install and Configure rclone with Google Cloud service account | ||
| run: | | ||
| 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 backend copyid gdrive: ${{ github.event.inputs.file_id }} tools/adhoc.xlsx | ||
|
|
||
| - name: Run script | ||
| run: | | ||
| 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" | ||
| team-reviewers: | | ||
| Women-Coding-Community/leaders | ||
| 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. | ||
|
|
||
| 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,144 @@ | ||
| """ | ||
| 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 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 | ||
| """ | ||
|
|
||
| if len(current_availability) > 1 or mentor.get('hours') > 3: | ||
| return 500 | ||
|
|
||
| return 200 | ||
|
khairahscorner marked this conversation as resolved.
|
||
|
|
||
|
|
||
| def get_unavailable_mentor_sort(mentor): | ||
| """ | ||
| 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 | ||
| """ | ||
| if mentor.get("disabled", True): | ||
| return 1 | ||
|
|
||
| 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) | ||
| - If hours column in spreadsheet is empty/non-numeric, the value will be None (indicating existing hours should be kept) | ||
| """ | ||
| availability_update_dict = {} | ||
|
|
||
| for _, row in available_mentors.iterrows(): | ||
| mentor_name = row['Mentor Name'].strip() | ||
| updated_hours = row['Availability (Hours)'] | ||
|
|
||
| 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): | ||
| """ | ||
| 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) | ||
|
|
||
| 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 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', []) | ||
| mentor['sort'] = get_available_mentor_sort(mentor, current_availability) | ||
| mentor['availability'] = [month] | ||
|
|
||
| # 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}") | ||
| mentor['hours'] = updated_hours | ||
|
|
||
| with open(yml_file_path, 'w') as f: | ||
| yaml.default_flow_style = True | ||
| yaml.dump(mentors, f) | ||
|
|
||
| print(f"Mentor availabilities 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() | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
Binary file not shown.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.