Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions issues/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# .NET API Documentation Issue Generator

This project automates the creation of GitHub issues for documenting undocumented .NET APIs. It processes Excel compliance data and generates markdown templates for both individual namespace issues and a main tracking issue.

## Prerequisites

1. **PowerShell 7+** - Modern PowerShell version
2. **ImportExcel Module** - For reading Excel files: `Install-Module ImportExcel`
3. **GitHub CLI** - For creating issues: Install from [cli.github.com](https://cli.github.com)
4. **Excel Data File** - Compliance spreadsheet with API data

## Quick Start

### Step 1: Generate Markdown Issues

```powershell
pwsh generate_markdown_issues.ps1 -ExcelFile UndocAPIReport_github.com_dotnet_dotnet-api-docs_main_dotnet-api-docs.xlsx -DotNetVersion 10.0
```

This creates:
- `artifacts/namespace_issues/*.md` - Individual namespace issues
- `artifacts/main_issue.md` - Main tracking issue template
- `artifacts/issue_data.json` - Summary data

### Step 2: Create GitHub Issues

```powershell
pwsh create_github_issues.ps1 -Repo "owner/repo"
```

This creates:
- 1 main tracking issue from the generated template
- Individual namespace issues (count varies by .NET version)

## Generated Outputs

## File Structure

```
undocAPI/
├── generate_markdown_issues.ps1 # Generate markdown from Excel data
├── create_github_issues.ps1 # Create GitHub issues from markdown
├── templates/ # Issue templates (editable)
│ ├── main_issue_template.md # Main tracking issue template
│ └── namespace_issue_template.md # Namespace issue template
├── artifacts/ # Generated files (safe to delete)
│ ├── namespace_issues/ # Individual namespace markdown files
│ ├── main_issue.md # Main tracking issue template
│ └── issue_data.json # Summary data
└── UndocAPIReport_*.xlsx # Source Excel compliance data
```

## Template System

The system uses editable template files in the `templates/` directory:

### Template Variables
Templates use `{{VARIABLE_NAME}}` syntax for replacements:
- `{{DOTNET_VERSION}}` - .NET version (e.g., "10.0")
- `{{TOTAL_APIS}}` - Total API count
- `{{TOTAL_NAMESPACES}}` - Total namespace count
- `{{NAMESPACE}}` - Namespace name
- `{{API_COUNT}}` - APIs in namespace
- `{{API_LIST}}` - Generated API list
- `{{NAMESPACE_CHECKLIST}}` - Generated namespace checklist

### Template Comments
Comments in templates (between `<!-- -->`) are automatically removed during processing and can contain documentation about variables and formatting.

## Configuration

### .NET Version
Use the `-DotNetVersion` parameter:
```powershell
pwsh generate_markdown_issues.ps1 -DotNetVersion "11.0"
```

### Repository
Use the `-Repo` parameter:
```powershell
pwsh create_github_issues.ps1 -Repo "ericstj/scratch"
```

## Linking Workflow

The system creates bidirectional links between issues:

1. **Main Tracking Issue**: Created first with placeholders for namespace issue numbers
2. **Namespace Issues**: Created with links back to the main tracking issue
3. **Link Updates**: Main tracking issue is automatically updated with actual namespace issue numbers

### Issue Cross-References
- Each namespace issue links to the main tracking issue: "Please follow the instructions in the main tracking issue (#123)"
- The main tracking issue links to each namespace issue: "- [ ] **Namespace** (X APIs) - #456"

## Data Sources

The system reads from the Excel compliance spreadsheet and filters for:
- APIs matching the specified .NET version
- Non-null API links with proper formatting
- Grouped by namespace for organization

## Clean Workflow

1. **Generate** → `pwsh generate_markdown_issues.ps1 -DotNetVersion "X.X"`
2. **Review** → Check `artifacts/` directory contents
3. **Deploy** → `pwsh create_github_issues.ps1 -Repo "owner/repo"`

The `artifacts/` directory can be safely deleted and regenerated at any time.
204 changes: 204 additions & 0 deletions issues/create_github_issues.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
# Create GitHub issues from generated markdown files
#
# This script reads markdown files from artifacts/namespace_issues/ and creates:
# - 1 main tracking issue from artifacts/main_issue.md
# - Individual namespace issues from artifacts/namespace_issues/
#
# Prerequisites:
# - GitHub CLI (gh) installed and authenticated
# - Generated markdown files from generate_markdown_issues.ps1
#
# Usage:
# pwsh create_github_issues.ps1 -Repo "owner/repo"

param(
[Parameter(Mandatory=$true)]
[string]$Repo
)

# Parse repository owner and name from format "owner/repo"
if ($Repo -notmatch '^([^/]+)/([^/]+)$') {
Write-Error "❌ Invalid repository format. Use: owner/repo (e.g., 'ericstj/scratch')"
exit 1
}

$RepoOwner = $Matches[1]
$RepoName = $Matches[2]

Write-Host "🎯 Target repository: $RepoOwner/$RepoName" -ForegroundColor Cyan

# Read summary data to get .NET version and counts
$SummaryFile = "artifacts\issue_data.json"
if (-not (Test-Path $SummaryFile)) {
Write-Error "❌ Summary file not found: $SummaryFile"
Write-Host "Please run generate_markdown_issues.ps1 first to create the artifacts." -ForegroundColor Yellow
exit 1
}

$SummaryData = Get-Content $SummaryFile | ConvertFrom-Json
$DotNetVersion = $SummaryData.dotnet_version
$TotalAPIs = $SummaryData.total_apis
$TotalNamespaces = $SummaryData.total_namespaces

Write-Host "🔄 Creating .NET $DotNetVersion documentation issues..." -ForegroundColor Green
Write-Host "📊 Will create $TotalNamespaces namespace issues for $TotalAPIs APIs" -ForegroundColor White

# Create main tracking issue
Write-Host "📝 Creating main tracking issue..."
$MainIssueFile = "artifacts\main_issue.md"

if (-not (Test-Path $MainIssueFile)) {
Write-Error "❌ Main issue template not found: $MainIssueFile"
Write-Host "Please run generate_markdown_issues.ps1 first to create the template." -ForegroundColor Yellow
exit 1
}

# Create the main tracking issue
Write-Host "📝 Creating main tracking issue..."
$MainIssueTitle = ".NET $DotNetVersion API Documentation Tracking Issue"
$MainIssueUrl = gh issue create --repo "$RepoOwner/$RepoName" --title $MainIssueTitle --body-file $MainIssueFile

if ($LASTEXITCODE -eq 0 -and -not [string]::IsNullOrEmpty($MainIssueUrl)) {
Write-Host "✅ Created main tracking issue: $MainIssueUrl" -ForegroundColor Green

# Extract the main issue number from the URL
$MainIssueNumber = ($MainIssueUrl -split '/')[-1]
Write-Host "📋 Main tracking issue number: #$MainIssueNumber" -ForegroundColor White
} else {
Write-Host "❌ Failed to create main tracking issue" -ForegroundColor Red
Write-Host "Please check your GitHub CLI authentication and repository permissions." -ForegroundColor Yellow
exit 1
}

# Create individual namespace issues
Write-Host "📚 Creating namespace issues..."
$NamespaceFiles = Get-ChildItem "artifacts\namespace_issues\*.md" | Where-Object { $_.Name -notlike "*_part*.md" } | Sort-Object Name
$CreatedCount = 0
$NamespaceIssueMap = @{}

foreach ($File in $NamespaceFiles) {
$Namespace = $File.BaseName.Replace('_', '.')
$Title = "$Namespace docs for .NET $DotNetVersion APIs"

Write-Host " Creating: $Title"

try {
# Read the template and replace the main tracking issue placeholder
$TemplateContent = Get-Content $File.FullName -Raw
$UpdatedContent = $TemplateContent -replace '#MAIN_TRACKING_ISSUE_NUMBER', "#$MainIssueNumber"

# Create a temporary file with updated content
$TempFile = [System.IO.Path]::GetTempFileName()
$UpdatedContent | Out-File -FilePath $TempFile -Encoding UTF8

$IssueUrl = gh issue create --repo "$RepoOwner/$RepoName" --title $Title --body-file $TempFile

# Clean up temp file
Remove-Item $TempFile -Force

if ($LASTEXITCODE -eq 0 -and -not [string]::IsNullOrEmpty($IssueUrl)) {
Write-Host " ✅ Created: $IssueUrl" -ForegroundColor Green
$CreatedCount++

# Extract issue number and store mapping
$IssueNumber = ($IssueUrl -split '/')[-1]
$NamespaceIssueMap[$Namespace] = $IssueNumber

# Check for split parts and add them as comments
$SafeName = $File.BaseName
$PartFiles = Get-ChildItem "artifacts\namespace_issues\$($SafeName)_part*.md" -ErrorAction SilentlyContinue

if ($PartFiles.Count -gt 0) {
Write-Host " 📝 Adding $($PartFiles.Count) comment parts..." -ForegroundColor Cyan

foreach ($PartFile in ($PartFiles | Sort-Object Name)) {
$PartContent = Get-Content $PartFile.FullName -Raw

try {
# Create a temporary file for the comment body to avoid command line length limits
$TempCommentFile = [System.IO.Path]::GetTempFileName()
$PartContent | Out-File -FilePath $TempCommentFile -Encoding UTF8

gh issue comment $IssueNumber --repo "$RepoOwner/$RepoName" --body-file $TempCommentFile | Out-Null

# Clean up temp file
Remove-Item $TempCommentFile -Force

if ($LASTEXITCODE -eq 0) {
Write-Host " ✅ Added comment from $($PartFile.Name)" -ForegroundColor Green
} else {
Write-Host " ❌ Failed to add comment from $($PartFile.Name)" -ForegroundColor Red
}
}
catch {
Write-Host " ❌ Error adding comment from $($PartFile.Name): $_" -ForegroundColor Red
}

# Small delay between comments
Start-Sleep -Milliseconds 100
}
}
} else {
Write-Host " ❌ Failed to create issue for $Namespace" -ForegroundColor Red
}

# Small delay to avoid rate limiting
Start-Sleep -Milliseconds 250
}
catch {
Write-Host " ❌ Failed to create issue for $Namespace : $_" -ForegroundColor Red
}
}

# Update the main tracking issue with actual namespace issue links
if ($NamespaceIssueMap.Count -gt 0) {
Write-Host "🔗 Updating main tracking issue with namespace issue links..."

try {
# Read the main issue template
$MainIssueContent = Get-Content $MainIssueFile -Raw

# Replace each namespace placeholder with actual issue number
# Sort by namespace length (longest first) to avoid substring matching issues
$SortedEntries = $NamespaceIssueMap.GetEnumerator() | Sort-Object { $_.Key.Length } -Descending

foreach ($NamespaceEntry in $SortedEntries) {
$Namespace = $NamespaceEntry.Key
$IssueNumber = $NamespaceEntry.Value
$SafeName = $Namespace -replace '\.', '_' -replace ' ', '_'

# Find and replace the exact placeholder with GitHub issue reference
$Pattern = "NAMESPACE_ISSUE_PLACEHOLDER_$([regex]::Escape($SafeName))\b"
$Replacement = "#$IssueNumber"
$MainIssueContent = $MainIssueContent -replace $Pattern, $Replacement
}

# Create temp file with updated content
$TempMainFile = [System.IO.Path]::GetTempFileName()
$MainIssueContent | Out-File -FilePath $TempMainFile -Encoding UTF8

# Update the main issue
gh issue edit $MainIssueNumber --repo "$RepoOwner/$RepoName" --body-file $TempMainFile | Out-Null

# Clean up temp file
Remove-Item $TempMainFile -Force

if ($LASTEXITCODE -eq 0) {
Write-Host "✅ Updated main tracking issue with namespace links" -ForegroundColor Green
} else {
Write-Host "⚠️ Failed to update main tracking issue with links" -ForegroundColor Yellow
}
}
catch {
Write-Host "⚠️ Failed to update main tracking issue: $_" -ForegroundColor Yellow
}
}

Write-Host "`n🎉 GitHub Issue Creation Complete!" -ForegroundColor Green
Write-Host "📊 Summary:" -ForegroundColor Yellow
Write-Host " - .NET version: $DotNetVersion" -ForegroundColor White
Write-Host " - Main tracking issue created" -ForegroundColor White
Write-Host " - Namespace issues created: $CreatedCount" -ForegroundColor White
Write-Host " - Total APIs to be documented: $TotalAPIs" -ForegroundColor White
Write-Host " - Repository: https://github.com/$RepoOwner/$RepoName/issues" -ForegroundColor White
Write-Host "`n✅ All issues created with properly formatted API links!" -ForegroundColor Green
Loading