This commit introduces several new files and updates to support SR&ED tracking and project management: - Adds a template for SR&ED tasks to standardize issue creation. - Adds a Makefile command to set up GitHub labels from a YAML file. - Adds a Makefile command to export SR&ED-eligible issues to a Markdown file. - Adds a Makefile command to create issues from a file. - Adds documentation for SR&ED tracking and development conventions. - Adds a YAML file to define GitHub labels. - Adds scripts to set up GitHub labels, export issues, and create issues from a file. - Updates the project plan to include SR&ED considerations. These changes aim to improve project organization, facilitate SR&ED claims, and streamline development workflows.
93 lines
2.9 KiB
Python
Executable File
93 lines
2.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
||
import subprocess
|
||
import os
|
||
import re
|
||
|
||
# --- Configuration ---
|
||
INPUT_FILE = "issues-to-create.md"
|
||
PROJECT_TITLE = "Krow"
|
||
# ---
|
||
|
||
def create_issue(title, body, labels, milestone):
|
||
"""Creates a GitHub issue using the gh CLI."""
|
||
command = ["gh", "issue", "create"]
|
||
command.extend(["--title", title])
|
||
command.extend(["--body", body])
|
||
command.extend(["--project", PROJECT_TITLE])
|
||
|
||
if milestone:
|
||
command.extend(["--milestone", milestone])
|
||
|
||
for label in labels:
|
||
command.extend(["--label", label])
|
||
|
||
print(f" -> Creating issue: \"{title}\"")
|
||
|
||
try:
|
||
result = subprocess.run(command, check=True, text=True, capture_output=True)
|
||
print(result.stdout.strip())
|
||
except subprocess.CalledProcessError as e:
|
||
print(f"❌ ERROR: Failed to create issue '{title}'.")
|
||
print(f" Stderr: {e.stderr.strip()}")
|
||
|
||
|
||
def main():
|
||
"""Main function to parse the file and create issues."""
|
||
print(f"🚀 Starting bulk creation of GitHub issues from '{INPUT_FILE}'...")
|
||
|
||
if subprocess.run(["which", "gh"], capture_output=True).returncode != 0:
|
||
print("❌ ERROR: GitHub CLI (‘gh’) is not installed.")
|
||
exit(1)
|
||
if not os.path.exists(INPUT_FILE):
|
||
print(f"❌ ERROR: Input file ‘{INPUT_FILE}’ not found.")
|
||
exit(1)
|
||
print("✅ Dependencies and input file found.")
|
||
|
||
print(f"2. Reading and parsing ‘{INPUT_FILE}’...")
|
||
with open(INPUT_FILE, 'r') as f:
|
||
content = f.read()
|
||
|
||
# Split the content by lines starting with '# '
|
||
issue_blocks = re.split(r'\n(?=#\s)', content)
|
||
|
||
for block in issue_blocks:
|
||
if not block.strip():
|
||
continue
|
||
|
||
lines = block.strip().split('\n')
|
||
|
||
title = lines[0].replace('# ', '').strip()
|
||
|
||
labels_line = ""
|
||
milestone_line = ""
|
||
body_start_index = 1
|
||
|
||
# Find all metadata lines (Labels, Milestone) at the beginning of the body
|
||
for i, line in enumerate(lines[1:]):
|
||
line_lower = line.strip().lower()
|
||
if line_lower.startswith('labels:'):
|
||
labels_line = line.split(':', 1)[1].strip()
|
||
elif line_lower.startswith('milestone:'):
|
||
milestone_line = line.split(':', 1)[1].strip()
|
||
elif line.strip() == "":
|
||
continue # Ignore blank lines in the metadata header
|
||
else:
|
||
# This is the first real line of the body
|
||
body_start_index = i + 1
|
||
break
|
||
|
||
body = "\n".join(lines[body_start_index:]).strip()
|
||
labels = [label.strip() for label in labels_line.split(',') if label.strip()]
|
||
milestone = milestone_line
|
||
|
||
if not title:
|
||
print("⚠️ Skipping block with no title.")
|
||
continue
|
||
|
||
create_issue(title, body, labels, milestone)
|
||
|
||
print("\n🎉 Bulk issue creation complete!")
|
||
|
||
if __name__ == "__main__":
|
||
main()
|