Useful for teams that have been tracking issues in .csv compatible formats like a spreadsheet and now want to move to GitHub Issues. Automatically creates a GitHub repository, project, and imports sample issues with custom fields from a CSV file, in a comprehensive Bash script with embedded Python.
-
Repository Management
- Creates new GitHub repositories or uses existing ones
- Supports both personal and organization repositories
- Automatic conflict detection and resolution options
-
Project Management
- Creates GitHub Projects (v2) with custom fields
- Detects and handles existing projects
- Supports multiple field types (Single Select, Number, Date, Text)
- Automatic field type detection and mapping
-
CSV Import
- Bulk import issues from CSV files
- Maps CSV columns to GitHub Project custom fields
- Preserves field relationships and data types
- Handles special characters and formatting
-
Advanced Field Handling
- Automatic detection of field types even when API returns generic types
- Proper handling of NUMBER and DATE fields with correct CLI flags
- Single Select fields with predefined options
- Field name conflict resolution (e.g., Status β WorkflowState)
- GitHub CLI (gh): Install from https://cli.github.com/
- Python 3: Required for CSV processing and API interactions
- GitHub Authentication: Run
gh auth loginbefore using the script
- Clone this repository:
git clone https://github.com/yourusername/github-project-builder.git
cd github-project-builder- Make the script executable:
chmod +x create-github-project-v4.shEdit the configuration variables at the top of the script:
REPO_NAME="test-project-demo" # Repository name
PROJECT_NAME="Project Management Board" # Project name
CSV_FILE="test-issues.csv" # Path to CSV file
PROJECT_SCOPE="user" # "user" or "org"
ORG_NAME="" # Required if PROJECT_SCOPE="org"Your CSV file should have the following structure:
Title,Description,Priority,Status,EstimatedHours,DueDate,Team
"API endpoint refactoring","Refactor REST API endpoints for better performance","High","Todo",16,2025-09-01,"Backend"
"Create user dashboard","Design and implement user dashboard","Medium","In Progress",24,2025-09-10,"Frontend"- Title: Issue title (required)
- Description: Issue description (required)
- Priority: Single select (High, Medium, Low)
- Status: Single select (Todo, In Progress, Done, Blocked) - mapped to WorkflowState
- EstimatedHours: Number field
- DueDate: Date field (YYYY-MM-DD format)
- Team: Single select (Frontend, Backend, API, Database, etc.)
./create-github-project-v4.sh# Edit the script to set:
PROJECT_SCOPE="org"
ORG_NAME="your-org-name"
./create-github-project-v4.shThe script detects existing repositories and projects, offering options to:
- Use existing resources
- Create new ones with different names
- Cancel the operation
The script includes advanced logic to detect field types even when GitHub's API returns generic types:
# Known field type mappings for fallback
known_types = {
'EstimatedHours': 'NUMBER',
'DueDate': 'DATE',
'Priority': 'SINGLE_SELECT',
'WorkflowState': 'SINGLE_SELECT',
'Team': 'SINGLE_SELECT'
}Different field types are handled with appropriate GitHub CLI flags:
--numberfor NUMBER fields--datefor DATE fields--single-select-option-idfor SINGLE_SELECT fields--textfor TEXT fields
The script automatically handles GitHub's reserved field names:
- Renames "Status" to "WorkflowState" to avoid conflicts
- Skips creation of built-in fields like Title and Description
The script includes debug output for the first 2 issues to help troubleshoot field updates:
debug_mode = (i <= 2) # Debug first 2 issuesThe script can be extended with GraphQL mutations for more reliable field updates:
def update_field_via_graphql(project_id, item_id, field_id, value, field_type):
"""Update a field using GraphQL API directly."""
# GraphQL mutation for NUMBER fields
mutation = f'''
mutation {{
updateProjectV2ItemFieldValue(input: {{
projectId: "{project_id}"
itemId: "{item_id}"
fieldId: "{field_id}"
value: {{ number: {value} }}
}}) {{
projectV2Item {{ id }}
}}
}}
'''Built-in delays prevent hitting GitHub's rate limits:
time.sleep(1) # Rate limiting between operationsComprehensive error handling with colored output:
- π΄ Red: Critical errors
- π‘ Yellow: Warnings and prompts
- π’ Green: Success messages
- π΅ Blue: Information
- π£ Magenta: Debug information
If NUMBER or DATE fields aren't updating:
- Check the debug output to verify field type detection
- Ensure dates are in YYYY-MM-DD format
- Verify numbers are valid (integers or floats)
This usually means:
- The field name in CSV doesn't match the project field
- The field hasn't been created yet
- There's a conflict with reserved field names
# Check authentication status
gh auth status
# Re-authenticate if needed
gh auth login- v1: Basic repository and project creation
- v2: Added CSV import functionality
- v3: Enhanced conflict resolution and field mapping
- v4: Advanced field type detection and proper update handling
Contributions are welcome! Please feel free to submit pull requests or open issues for bugs and feature requests.
MIT License - feel free to use and modify for your needs.
This script was developed through iterative improvements to handle the complexities of GitHub's Project V2 API and provide a reliable way to bulk import issues with custom fields.