ALDashboard.project_maintenance
GitHub Project Maintenance Tool for Docassemble
This module provides command-line tools for automating GitHub repository maintenance tasks across multiple repositories, particularly for Docassemble packages. It enables bulk operations like adding issues, managing tags, and linking issues to GitHub projects.
PREREQUISITES:
- 
Install required dependencies: pip install PyGithub 
- 
GitHub Personal Access Token (PAT): You need a GitHub Personal Access Token with the following permissions: 
- repo (full control of private repositories)
- admin:org (for organization operations)
- project (for GitHub Projects v2 access)
Create one at: https://github.com/settings/tokens
AVAILABLE COMMANDS:
- 
get_package_names Gets package names from a Docassemble server. 
- 
add_tag_to_repos Adds a topic/tag to specific repositories. 
- 
process_packages_and_add_tag Gets packages from a Docassemble server and adds tags to corresponding repositories. 
- 
add_issues_and_create_cards Creates issues across repositories with a specific topic and adds them to a GitHub project. 
- 
link_issues Links existing issues with specific titles to a GitHub project. 
USAGE EXAMPLES:
Basic Usage:
python project_maintenance.py <command> [arguments]
- 
Get package names from a Docassemble server: python project_maintenance.py get_package_names courtformsonline.org 
- 
Add a tag to specific repositories: python project_maintenance.py add_tag_to_repos 
 YOUR_GITHUB_TOKEN
 SuffolkLITLab
 docassemble-ALAffidavitOfIndigency docassemble-ALDocument
 legal-tech
- 
Process packages from server and add tags: python project_maintenance.py process_packages_and_add_tag 
 courtformsonline.org
 YOUR_GITHUB_TOKEN
 SuffolkLITLab
 assembly-line
- 
Add issues across repositories and create project cards: python project_maintenance.py add_issues_and_create_cards 
 YOUR_GITHUB_TOKEN
 SuffolkLITLab
 "Assembly Line Maintenance"
 assembly-line
 "Update documentation"
 "Please update the README.md file with current installation instructions."
- 
Link existing issues to a project: python project_maintenance.py link_issues 
 YOUR_GITHUB_TOKEN
 SuffolkLITLab
 "Assembly Line Maintenance"
 assembly-line
 "Update documentation"
COMMON WORKFLOWS:
Workflow 1: Batch Issue Creation for Maintenance
Step 1: Create issues across all Assembly Line packages
python project_maintenance.py add_issues_and_create_cards 
YOUR_GITHUB_TOKEN 
SuffolkLITLab 
"Q1 2024 Maintenance" 
assembly-line 
"Security audit required" 
"Please review and update dependencies for security vulnerabilities. See issue template for checklist."
Workflow 2: Repository Organization
Step 1: Get packages from production server
python project_maintenance.py get_package_names courtformsonline.org
Step 2: Add organization tags based on server packages
python project_maintenance.py process_packages_and_add_tag 
courtformsonline.org 
YOUR_GITHUB_TOKEN 
SuffolkLITLab 
production-ready
Workflow 3: Project Management
Step 1: Create issues for a new initiative
python project_maintenance.py add_issues_and_create_cards 
YOUR_GITHUB_TOKEN 
SuffolkLITLab 
"Accessibility Improvements" 
assembly-line 
"WCAG 2.1 Compliance Review" 
"Review forms for WCAG 2.1 AA compliance. Focus on: keyboard navigation, screen reader compatibility, color contrast, and form labels."
Step 2: Later, link related existing issues
python project_maintenance.py link_issues 
YOUR_GITHUB_TOKEN 
SuffolkLITLab 
"Accessibility Improvements" 
assembly-line 
"Screen reader compatibility"
AUTHENTICATION SECURITY:
- Never commit your GitHub token to version control
- Use environment variables: export GITHUB_TOKEN=your_token_here
- Then use: $GITHUB_TOKEN in place of YOUR_GITHUB_TOKEN in examples
- Consider using GitHub CLI authentication: gh auth token
TIPS:
- Use quotes around multi-word arguments (project names, issue titles, etc.)
- Repository names are automatically converted from package names (dots become hyphens)
- The script filters repositories by GitHub topics/tags for targeted operations
- GitHub Projects v2 (Next-Generation) are required for project operations
- Large batch operations may hit GitHub API rate limits - the script includes error handling
For more information, see: https://github.com/SuffolkLITLab/docassemble-ALDashboard
get_package_names
def get_package_names(server_name: str) -> List[str]
Fetches the JSON file from the given Docassemble server and extracts package names.
Arguments
- server_namestr - Name or IP address of the Docassemble server.
Returns
- List[str]- List of package names.
add_tag_to_repos
def add_tag_to_repos(token: str, org_name: str, repo_names: List[str],
                     tag: str) -> None
Adds a specific tag to each repository in the given list.
Arguments
- 
tokenstr - GitHub Personal Access Token (PAT) with appropriate permissions.
- 
org_namestr - Name of the GitHub organization.
- 
repo_namesList[str] - List of repository names to which the tag will be added.
- 
tagstr - The tag to be added to the repositories.This function iterates through each repository in the provided list, fetching the current topics (tags) of the repository. If the specified tag is not already present, it adds the tag to the repository. The function includes error handling to catch and print any errors that occur while processing each repository. Example usage: personal_access_token = "YOUR_PERSONAL_ACCESS_TOKEN" organization_name = "YourOrgName" repositories = ["repo1", "repo2", "repo3"] tag_to_add = "your-tag" add_tag_to_repos(personal_access_token, organization_name, repositories, tag_to_add) 
process_packages_and_add_tag
def process_packages_and_add_tag(server_name: str, token: str, org_name: str,
                                 tag: str) -> None
Fetches package names from a Docassemble server, transforms them into repository names, and adds a specified tag to each repository.
Arguments
- server_namestr - Name or IP address of the Docassemble server.
- tokenstr - GitHub Personal Access Token.
- org_namestr - Name of the GitHub organization.
- tagstr - Tag to be added to each repository.
get_project_by_name
def get_project_by_name(token: str, org_name: str,
                        project_name: str) -> Optional[dict]
Finds a GitHub Next-Generation project by its name within an organization using GraphQL API.
Arguments
- tokenstr - GitHub Personal Access Token.
- org_namestr - Name of the GitHub organization.
- project_namestr - Name of the GitHub project.
Returns
- dict- The GitHub project object, or None if not found.
get_repos_by_topic
def get_repos_by_topic(token: str, org_name: str,
                       topic: str) -> List[Repository]
Fetches repositories in an organization that have a specific topic.
Arguments
- tokenstr - GitHub Personal Access Token.
- org_namestr - Name of the GitHub organization.
- topicstr - The GitHub topic to filter repositories by.
Returns
- List[Repository]- A list of repository objects that have the specified topic.
add_issues_and_create_cards
def add_issues_and_create_cards(token: str, org_name: str, project_name: str,
                                topic: str, issue_title: str,
                                issue_body: str) -> None
Adds an issue to each repository with a specific topic and creates a card for each issue in a Next-Generation GitHub project.
Arguments
- tokenstr - GitHub Personal Access Token.
- org_namestr - Name of the GitHub organization.
- project_namestr - Name of the GitHub project.
- topicstr - The GitHub topic to filter repositories by.
- issue_titlestr - Title of the issue.
- issue_bodystr - Body of the issue.
find_issues_by_title
def find_issues_by_title(token: str, org_name: str, repo_names: List[str],
                         issue_title: str) -> List[str]
Finds issues in a list of repositories with a specific title.
Arguments
- tokenstr - GitHub Personal Access Token.
- org_namestr - Name of the GitHub organization.
- repo_nameslist - List of repository names.
- issue_titlestr - Title of the issue to be found.
Returns
- list- A list of issue node IDs.
add_issue_to_project
def add_issue_to_project(token: str, project_id: str,
                         issue_node_id: str) -> None
Adds an issue to a Next-Generation GitHub project.
Arguments
- tokenstr - GitHub Personal Access Token.
- project_idstr - Node ID of the GitHub project.
- issue_node_idstr - Node ID of the GitHub issue.
link_issue_title_to_project
def link_issue_title_to_project(token: str, org_name: str, project_name: str,
                                topic: str, issue_title: str) -> None
Links issues with a specific title in repositories with a certain topic to a Next-Generation project.
Arguments
- tokenstr - GitHub Personal Access Token.
- org_namestr - Name of the GitHub organization.
- project_namestr - Name of the GitHub project.
- topicstr - The GitHub topic to filter repositories by.
- issue_titlestr - Title of the issue to link.
main
def main() -> None
Main function to run the specified project maintenance command.