mirror of
https://github.com/HDFGroup/hdf5.git
synced 2026-09-25 04:09:44 +03:00
Update release progress badges to use Priority-based categorization (#6270)
* Update release progress badges to use Priority-based categorization - Replace "Release Blockers"/"Release Must Do" with "Critical Priority"/"High Priority" - Switch issue filtering from Release gating field to Priority field (P0 - Critical/P1 - High) - Remove "Nice to Have" badge from workflow and README - Add failure step: on workflow error, update both badge gist files to bright purple (BF00FF) with "FAILURE" message - Version auto-detected from src/H5public.h for milestone filtering * Fix stale class docstring: release blocker -> priority issue
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Badge Generation and Gist Update Script
|
||||
# Generates badges for release blocker and must-do progress and updates GitHub Gist
|
||||
# Generates badges for critical and high priority issue progress and updates GitHub Gist
|
||||
#
|
||||
# Environment Variables Required:
|
||||
# GITHUB_TOKEN - GitHub token for Gist API access
|
||||
@@ -11,12 +11,10 @@
|
||||
# PERCENTAGE - Overall completion percentage
|
||||
# DONE - Number of completed items
|
||||
# TOTAL - Total number of items
|
||||
# BLOCKER_DONE - Number of completed blockers
|
||||
# BLOCKER_TOTAL - Total number of blockers
|
||||
# MUSTDO_DONE - Number of completed must-dos
|
||||
# MUSTDO_TOTAL - Total number of must-dos
|
||||
# NICETOHAVE_DONE - Number of completed nice-to-haves
|
||||
# NICETOHAVE_TOTAL - Total number of nice-to-haves
|
||||
# BLOCKER_DONE - Number of completed critical priority items
|
||||
# BLOCKER_TOTAL - Total number of critical priority items
|
||||
# MUSTDO_DONE - Number of completed high priority items
|
||||
# MUSTDO_TOTAL - Total number of high priority items
|
||||
# VERSION - Version string (e.g., "2.1") - optional
|
||||
#
|
||||
|
||||
@@ -120,12 +118,6 @@ else
|
||||
MUSTDO_PERCENTAGE=$(awk "BEGIN {printf \"%.1f\", ($MUSTDO_DONE / $MUSTDO_TOTAL * 100)}")
|
||||
fi
|
||||
|
||||
if [ "$NICETOHAVE_TOTAL" -eq 0 ]; then
|
||||
NICETOHAVE_PERCENTAGE="-1.0"
|
||||
else
|
||||
NICETOHAVE_PERCENTAGE=$(awk "BEGIN {printf \"%.1f\", ($NICETOHAVE_DONE / $NICETOHAVE_TOTAL * 100)}")
|
||||
fi
|
||||
|
||||
# Determine colors using the shared function (use lightgrey for 0/0)
|
||||
if [ "$BLOCKER_PERCENTAGE" = "-1.0" ]; then
|
||||
BLOCKER_COLOR="lightgrey"
|
||||
@@ -139,56 +131,40 @@ else
|
||||
MUSTDO_COLOR=$(get_badge_color "$MUSTDO_PERCENTAGE")
|
||||
fi
|
||||
|
||||
if [ "$NICETOHAVE_PERCENTAGE" = "-1.0" ]; then
|
||||
NICETOHAVE_COLOR="lightgrey"
|
||||
else
|
||||
NICETOHAVE_COLOR=$(get_badge_color "$NICETOHAVE_PERCENTAGE")
|
||||
fi
|
||||
|
||||
# Determine badge labels - include version if available
|
||||
if [ -n "${VERSION:-}" ] && [ "$VERSION" != "all" ]; then
|
||||
BLOCKER_LABEL="${VERSION} Release Blockers"
|
||||
MUSTDO_LABEL="${VERSION} Release Must Do"
|
||||
NICETOHAVE_LABEL="${VERSION} Release Nice to Have"
|
||||
BLOCKER_LABEL="${VERSION} Critical Priority"
|
||||
MUSTDO_LABEL="${VERSION} High Priority"
|
||||
else
|
||||
BLOCKER_LABEL="Release Blockers"
|
||||
MUSTDO_LABEL="Release Must Do"
|
||||
NICETOHAVE_LABEL="Release Nice to Have"
|
||||
BLOCKER_LABEL="Critical Priority"
|
||||
MUSTDO_LABEL="High Priority"
|
||||
fi
|
||||
|
||||
# Create badge JSONs using the shared function
|
||||
BLOCKER_BADGE_JSON=$(create_badge_json "$BLOCKER_LABEL" "$BLOCKER_DONE" "$BLOCKER_TOTAL" "$BLOCKER_PERCENTAGE" "$BLOCKER_COLOR")
|
||||
MUSTDO_BADGE_JSON=$(create_badge_json "$MUSTDO_LABEL" "$MUSTDO_DONE" "$MUSTDO_TOTAL" "$MUSTDO_PERCENTAGE" "$MUSTDO_COLOR")
|
||||
NICETOHAVE_BADGE_JSON=$(create_badge_json "$NICETOHAVE_LABEL" "$NICETOHAVE_DONE" "$NICETOHAVE_TOTAL" "$NICETOHAVE_PERCENTAGE" "$NICETOHAVE_COLOR")
|
||||
|
||||
# Validate JSONs were created successfully
|
||||
if [ -z "$BLOCKER_BADGE_JSON" ] || ! echo "$BLOCKER_BADGE_JSON" | jq empty 2>/dev/null; then
|
||||
echo "::error::Failed to generate valid blocker badge JSON"
|
||||
echo "::error::Failed to generate valid critical priority badge JSON"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$MUSTDO_BADGE_JSON" ] || ! echo "$MUSTDO_BADGE_JSON" | jq empty 2>/dev/null; then
|
||||
echo "::error::Failed to generate valid must-do badge JSON"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$NICETOHAVE_BADGE_JSON" ] || ! echo "$NICETOHAVE_BADGE_JSON" | jq empty 2>/dev/null; then
|
||||
echo "::error::Failed to generate valid nice-to-have badge JSON"
|
||||
echo "::error::Failed to generate valid high priority badge JSON"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The filenames in the Gist
|
||||
BLOCKER_GIST_NAME="release-blocker-${GITHUB_REPOSITORY##*/}.json"
|
||||
MUSTDO_GIST_NAME="release-mustdo-${GITHUB_REPOSITORY##*/}.json"
|
||||
NICETOHAVE_GIST_NAME="release-nicetohave-${GITHUB_REPOSITORY##*/}.json"
|
||||
echo "::notice::Updating Gist files: $BLOCKER_GIST_NAME, $MUSTDO_GIST_NAME, $NICETOHAVE_GIST_NAME"
|
||||
echo "::notice::Updating Gist files: $BLOCKER_GIST_NAME, $MUSTDO_GIST_NAME"
|
||||
|
||||
# Create the request payload with all three files
|
||||
# Create the request payload with both files
|
||||
REQUEST_PAYLOAD=$(jq -n \
|
||||
--arg blocker_filename "$BLOCKER_GIST_NAME" \
|
||||
--arg mustdo_filename "$MUSTDO_GIST_NAME" \
|
||||
--arg nicetohave_filename "$NICETOHAVE_GIST_NAME" \
|
||||
--argjson blocker_content "$BLOCKER_BADGE_JSON" \
|
||||
--argjson mustdo_content "$MUSTDO_BADGE_JSON" \
|
||||
--argjson nicetohave_content "$NICETOHAVE_BADGE_JSON" \
|
||||
'{
|
||||
"files": {
|
||||
($blocker_filename): {
|
||||
@@ -196,9 +172,6 @@ REQUEST_PAYLOAD=$(jq -n \
|
||||
},
|
||||
($mustdo_filename): {
|
||||
"content": ($mustdo_content | tostring)
|
||||
},
|
||||
($nicetohave_filename): {
|
||||
"content": ($nicetohave_content | tostring)
|
||||
}
|
||||
}
|
||||
}')
|
||||
@@ -227,18 +200,15 @@ echo "::notice::Gist updated successfully"
|
||||
# Generate badge URLs for use in README
|
||||
BLOCKER_BADGE_URL="https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/${GITHUB_REPOSITORY_OWNER}-Bot/${GIST_ID}/raw/${BLOCKER_GIST_NAME}"
|
||||
MUSTDO_BADGE_URL="https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/${GITHUB_REPOSITORY_OWNER}-Bot/${GIST_ID}/raw/${MUSTDO_GIST_NAME}"
|
||||
NICETOHAVE_BADGE_URL="https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/${GITHUB_REPOSITORY_OWNER}-Bot/${GIST_ID}/raw/${NICETOHAVE_GIST_NAME}"
|
||||
PROJECT_URL="https://github.com/${GITHUB_REPOSITORY}/projects/39"
|
||||
|
||||
echo "::notice::Blocker Badge URL: $BLOCKER_BADGE_URL"
|
||||
echo "::notice::Must-Do Badge URL: $MUSTDO_BADGE_URL"
|
||||
echo "::notice::Nice-to-Have Badge URL: $NICETOHAVE_BADGE_URL"
|
||||
echo "::notice::Critical Priority Badge URL: $BLOCKER_BADGE_URL"
|
||||
echo "::notice::High Priority Badge URL: $MUSTDO_BADGE_URL"
|
||||
|
||||
# Output to GitHub Actions if GITHUB_OUTPUT is set
|
||||
if [ -n "${GITHUB_OUTPUT:-}" ]; then
|
||||
echo "blocker_badge_url=$BLOCKER_BADGE_URL" >> "$GITHUB_OUTPUT"
|
||||
echo "mustdo_badge_url=$MUSTDO_BADGE_URL" >> "$GITHUB_OUTPUT"
|
||||
echo "nicetohave_badge_url=$NICETOHAVE_BADGE_URL" >> "$GITHUB_OUTPUT"
|
||||
echo "project_url=$PROJECT_URL" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
@@ -250,35 +220,27 @@ if [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then
|
||||
**Status:** ${STATUS}
|
||||
**Overall Progress:** ${DONE} of ${TOTAL} items completed
|
||||
|
||||
### 🚫 Release Blockers
|
||||
### Critical Priority
|
||||
**Progress:** ${BLOCKER_DONE} of ${BLOCKER_TOTAL} completed (${BLOCKER_PERCENTAGE}%)
|
||||
**Badge Color:** ${BLOCKER_COLOR}
|
||||
|
||||
### ✅ Release Must Do
|
||||
### High Priority
|
||||
**Progress:** ${MUSTDO_DONE} of ${MUSTDO_TOTAL} completed (${MUSTDO_PERCENTAGE}%)
|
||||
**Badge Color:** ${MUSTDO_COLOR}
|
||||
|
||||
### 💡 Release Nice to Have
|
||||
**Progress:** ${NICETOHAVE_DONE} of ${NICETOHAVE_TOTAL} completed (${NICETOHAVE_PERCENTAGE}%)
|
||||
**Badge Color:** ${NICETOHAVE_COLOR}
|
||||
|
||||
**Gist ID:** ${GIST_ID}
|
||||
|
||||
### Badge URLs
|
||||
**Blocker Markdown:** \`[](${PROJECT_URL})\`
|
||||
**Must-Do Markdown:** \`[](${PROJECT_URL})\`
|
||||
**Nice-to-Have Markdown:** \`[](${PROJECT_URL})\`
|
||||
**Critical Priority Markdown:** \`[](${PROJECT_URL})\`
|
||||
**High Priority Markdown:** \`[](${PROJECT_URL})\`
|
||||
|
||||
### Badge JSON Preview
|
||||
\`\`\`json
|
||||
// Blocker Badge
|
||||
// Critical Priority Badge
|
||||
${BLOCKER_BADGE_JSON}
|
||||
|
||||
// Must-Do Badge
|
||||
// High Priority Badge
|
||||
${MUSTDO_BADGE_JSON}
|
||||
|
||||
// Nice-to-Have Badge
|
||||
${NICETOHAVE_BADGE_JSON}
|
||||
\`\`\`
|
||||
EOF
|
||||
fi
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
GitHub Project Release Blocker Progress Tracker
|
||||
Fetches release blocker issues from the HDF5 project and calculates completion percentage.
|
||||
GitHub Project Priority Issue Progress Tracker
|
||||
Fetches critical and high priority issues from the HDF5 project and calculates completion percentage.
|
||||
"""
|
||||
|
||||
import os
|
||||
@@ -22,13 +22,12 @@ class ProjectDataError(Exception):
|
||||
|
||||
# Configuration: Expected field names in GitHub Project
|
||||
# Update these if the project field names change
|
||||
FIELD_RELEASE_GATING = "Release gating"
|
||||
FIELD_PRIORITY = "Priority"
|
||||
FIELD_STATUS = "Status"
|
||||
|
||||
# Expected values for Release gating field
|
||||
VALUE_RELEASE_BLOCKER = "Release_Blocker"
|
||||
VALUE_RELEASE_MUST_DO = "Release_Must Do"
|
||||
VALUE_RELEASE_NICE_TO_HAVE = "Release_Nice to Have"
|
||||
# Expected values for Priority field
|
||||
VALUE_CRITICAL = "P0 - Critical"
|
||||
VALUE_HIGH = "P1 - High"
|
||||
|
||||
# Expected value for Status field when an item is completed
|
||||
VALUE_STATUS_DONE = "Done"
|
||||
@@ -39,7 +38,7 @@ DEFAULT_MILESTONE_FILTER = None # Will be set from environment or H5public.h
|
||||
|
||||
|
||||
class GitHubProjectTracker:
|
||||
"""Tracks release blocker progress in GitHub projects."""
|
||||
"""Tracks priority issue progress in GitHub projects."""
|
||||
|
||||
def __init__(self, token: str, owner: str, project_number: int, milestone_filter: Optional[str] = None):
|
||||
self.api_url = "https://api.github.com/graphql"
|
||||
@@ -126,22 +125,20 @@ class GitHubProjectTracker:
|
||||
|
||||
def fetch_release_blocker_stats(self) -> Dict[str, int]:
|
||||
"""
|
||||
Fetches release blocker, must-do, and nice-to-have statistics from the GitHub project.
|
||||
Fetches critical and high priority issue statistics from the GitHub project.
|
||||
|
||||
Returns:
|
||||
Dict with 'total', 'done', 'percentage', 'blocker_total', 'blocker_done',
|
||||
'mustdo_total', 'mustdo_done', 'nicetohave_total', 'nicetohave_done' keys
|
||||
'mustdo_total', 'mustdo_done' keys
|
||||
"""
|
||||
blocker_total = 0
|
||||
blocker_done = 0
|
||||
mustdo_total = 0
|
||||
mustdo_done = 0
|
||||
nicetohave_total = 0
|
||||
nicetohave_done = 0
|
||||
cursor = None
|
||||
|
||||
# Track if we've seen the expected fields at least once
|
||||
seen_release_gating = False
|
||||
seen_priority = False
|
||||
seen_status = False
|
||||
|
||||
while True:
|
||||
@@ -189,26 +186,22 @@ class GitHubProjectTracker:
|
||||
fields = self._parse_item_fields(item)
|
||||
|
||||
# Validate expected fields exist
|
||||
if FIELD_RELEASE_GATING in fields:
|
||||
seen_release_gating = True
|
||||
if FIELD_PRIORITY in fields:
|
||||
seen_priority = True
|
||||
if FIELD_STATUS in fields:
|
||||
seen_status = True
|
||||
|
||||
release_gating = fields.get(FIELD_RELEASE_GATING, "")
|
||||
priority = fields.get(FIELD_PRIORITY, "")
|
||||
status = fields.get(FIELD_STATUS, "")
|
||||
|
||||
if release_gating == VALUE_RELEASE_BLOCKER:
|
||||
if priority == VALUE_CRITICAL:
|
||||
blocker_total += 1
|
||||
if status == VALUE_STATUS_DONE:
|
||||
blocker_done += 1
|
||||
elif release_gating == VALUE_RELEASE_MUST_DO:
|
||||
elif priority == VALUE_HIGH:
|
||||
mustdo_total += 1
|
||||
if status == VALUE_STATUS_DONE:
|
||||
mustdo_done += 1
|
||||
elif release_gating == VALUE_RELEASE_NICE_TO_HAVE:
|
||||
nicetohave_total += 1
|
||||
if status == VALUE_STATUS_DONE:
|
||||
nicetohave_done += 1
|
||||
|
||||
# Check for next page
|
||||
page_info = items.get("pageInfo", {})
|
||||
@@ -217,18 +210,18 @@ class GitHubProjectTracker:
|
||||
cursor = page_info.get("endCursor")
|
||||
|
||||
# Validate that expected fields were found - FAIL HARD if missing
|
||||
# This prevents false positives where field renames would cause 0 blockers to be reported
|
||||
if not seen_release_gating:
|
||||
print(f"ERROR: Critical field '{FIELD_RELEASE_GATING}' not found in any project items.",
|
||||
# This prevents false positives where field renames would cause 0 items to be reported
|
||||
if not seen_priority:
|
||||
print(f"ERROR: Critical field '{FIELD_PRIORITY}' not found in any project items.",
|
||||
file=sys.stderr)
|
||||
print("This field is required to identify release blockers and must-do items.",
|
||||
print("This field is required to identify critical and high priority items.",
|
||||
file=sys.stderr)
|
||||
print("Possible causes:", file=sys.stderr)
|
||||
print(f" 1. Field '{FIELD_RELEASE_GATING}' was renamed in the project", file=sys.stderr)
|
||||
print(f" 1. Field '{FIELD_PRIORITY}' was renamed in the project", file=sys.stderr)
|
||||
print(" 2. Project structure changed", file=sys.stderr)
|
||||
print(" 3. Project is empty or inaccessible", file=sys.stderr)
|
||||
print("Action required: Update FIELD_RELEASE_GATING constant in this script.", file=sys.stderr)
|
||||
raise ProjectFieldMissingError(f"Critical field '{FIELD_RELEASE_GATING}' not found")
|
||||
print("Action required: Update FIELD_PRIORITY constant in this script.", file=sys.stderr)
|
||||
raise ProjectFieldMissingError(f"Critical field '{FIELD_PRIORITY}' not found")
|
||||
|
||||
if not seen_status:
|
||||
print(f"ERROR: Critical field '{FIELD_STATUS}' not found in any project items.",
|
||||
@@ -248,19 +241,19 @@ class GitHubProjectTracker:
|
||||
# If total is 0, either the project is empty or field matching failed
|
||||
if total == 0:
|
||||
if self.milestone_filter:
|
||||
print(f"INFO: No release blocker or must-do items found for milestone '{self.milestone_filter}'.", file=sys.stderr)
|
||||
print(f"INFO: No critical or high priority items found for milestone '{self.milestone_filter}'.", file=sys.stderr)
|
||||
print("This may be expected if no items exist for this milestone yet.", file=sys.stderr)
|
||||
# Don't fail - return N/A indicators when filtering by milestone with no items
|
||||
percentage = -1.0 # Use -1 to indicate N/A
|
||||
else:
|
||||
print("ERROR: No release blocker or must-do items found (total=0).", file=sys.stderr)
|
||||
print("ERROR: No critical or high priority items found (total=0).", file=sys.stderr)
|
||||
print("This likely indicates:", file=sys.stderr)
|
||||
print(f" 1. The '{FIELD_RELEASE_GATING}' field values changed", file=sys.stderr)
|
||||
print(f" Expected values: '{VALUE_RELEASE_BLOCKER}' or '{VALUE_RELEASE_MUST_DO}'", file=sys.stderr)
|
||||
print(f" 1. The '{FIELD_PRIORITY}' field values changed", file=sys.stderr)
|
||||
print(f" Expected values: '{VALUE_CRITICAL}' or '{VALUE_HIGH}'", file=sys.stderr)
|
||||
print(" 2. Project has no items with these field values", file=sys.stderr)
|
||||
print(" 3. Field matching logic needs to be updated", file=sys.stderr)
|
||||
print("Refusing to report 0% or 100% with no items to prevent false positives.", file=sys.stderr)
|
||||
raise ProjectDataError("No release items found - refusing to report false completion status")
|
||||
raise ProjectDataError("No priority items found - refusing to report false completion status")
|
||||
else:
|
||||
percentage = round((done / total * 100), 1)
|
||||
|
||||
@@ -271,9 +264,7 @@ class GitHubProjectTracker:
|
||||
'blocker_total': blocker_total,
|
||||
'blocker_done': blocker_done,
|
||||
'mustdo_total': mustdo_total,
|
||||
'mustdo_done': mustdo_done,
|
||||
'nicetohave_total': nicetohave_total,
|
||||
'nicetohave_done': nicetohave_done
|
||||
'mustdo_done': mustdo_done
|
||||
}
|
||||
|
||||
|
||||
@@ -346,8 +337,6 @@ def main():
|
||||
f.write(f"blocker_done={stats['blocker_done']}\n")
|
||||
f.write(f"mustdo_total={stats['mustdo_total']}\n")
|
||||
f.write(f"mustdo_done={stats['mustdo_done']}\n")
|
||||
f.write(f"nicetohave_total={stats['nicetohave_total']}\n")
|
||||
f.write(f"nicetohave_done={stats['nicetohave_done']}\n")
|
||||
f.write(f"version={MILESTONE_FILTER or 'all'}\n")
|
||||
|
||||
# Also output to stdout for local testing
|
||||
@@ -356,14 +345,11 @@ def main():
|
||||
print(f"blocker_total={stats['blocker_total']}")
|
||||
print(f"mustdo_done={stats['mustdo_done']}")
|
||||
print(f"mustdo_total={stats['mustdo_total']}")
|
||||
print(f"nicetohave_done={stats['nicetohave_done']}")
|
||||
print(f"nicetohave_total={stats['nicetohave_total']}")
|
||||
print(f"version={MILESTONE_FILTER or 'all'}")
|
||||
print(f"Calculated progress: {stats['percentage']}%")
|
||||
print(f"Done / Total: {stats['done']} / {stats['total']}")
|
||||
print(f"Blockers: {stats['blocker_done']} / {stats['blocker_total']}")
|
||||
print(f"Must Do: {stats['mustdo_done']} / {stats['mustdo_total']}")
|
||||
print(f"Nice to Have: {stats['nicetohave_done']} / {stats['nicetohave_total']}")
|
||||
print(f"Critical Priority: {stats['blocker_done']} / {stats['blocker_total']}")
|
||||
print(f"High Priority: {stats['mustdo_done']} / {stats['mustdo_total']}")
|
||||
if MILESTONE_FILTER:
|
||||
print(f"Milestone filter: {MILESTONE_FILTER}")
|
||||
|
||||
|
||||
@@ -115,13 +115,11 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract blocker, must-do, and nice-to-have counts
|
||||
# Extract critical and high priority counts
|
||||
BLOCKER_DONE=$(grep "^blocker_done=" progress_output.txt | cut -d'=' -f2 | head -1)
|
||||
BLOCKER_TOTAL=$(grep "^blocker_total=" progress_output.txt | cut -d'=' -f2 | head -1)
|
||||
MUSTDO_DONE=$(grep "^mustdo_done=" progress_output.txt | cut -d'=' -f2 | head -1)
|
||||
MUSTDO_TOTAL=$(grep "^mustdo_total=" progress_output.txt | cut -d'=' -f2 | head -1)
|
||||
NICETOHAVE_DONE=$(grep "^nicetohave_done=" progress_output.txt | cut -d'=' -f2 | head -1)
|
||||
NICETOHAVE_TOTAL=$(grep "^nicetohave_total=" progress_output.txt | cut -d'=' -f2 | head -1)
|
||||
VERSION=$(grep "^version=" progress_output.txt | cut -d'=' -f2 | head -1)
|
||||
|
||||
# Set outputs for use in subsequent steps
|
||||
@@ -132,12 +130,10 @@ jobs:
|
||||
echo "blocker_total=$BLOCKER_TOTAL" >> $GITHUB_OUTPUT
|
||||
echo "mustdo_done=$MUSTDO_DONE" >> $GITHUB_OUTPUT
|
||||
echo "mustdo_total=$MUSTDO_TOTAL" >> $GITHUB_OUTPUT
|
||||
echo "nicetohave_done=$NICETOHAVE_DONE" >> $GITHUB_OUTPUT
|
||||
echo "nicetohave_total=$NICETOHAVE_TOTAL" >> $GITHUB_OUTPUT
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
echo "::notice::Progress calculation successful: ${PERCENTAGE}% (${DONE}/${TOTAL})"
|
||||
echo "::notice:: Version: ${VERSION}, Blockers: ${BLOCKER_DONE}/${BLOCKER_TOTAL}, Must Do: ${MUSTDO_DONE}/${MUSTDO_TOTAL}, Nice to Have: ${NICETOHAVE_DONE}/${NICETOHAVE_TOTAL}"
|
||||
echo "::notice:: Version: ${VERSION}, Critical Priority: ${BLOCKER_DONE}/${BLOCKER_TOTAL}, High Priority: ${MUSTDO_DONE}/${MUSTDO_TOTAL}"
|
||||
|
||||
# Clean up
|
||||
rm -f progress_output.txt
|
||||
@@ -158,17 +154,52 @@ jobs:
|
||||
BLOCKER_TOTAL: ${{ steps.progress.outputs.blocker_total }}
|
||||
MUSTDO_DONE: ${{ steps.progress.outputs.mustdo_done }}
|
||||
MUSTDO_TOTAL: ${{ steps.progress.outputs.mustdo_total }}
|
||||
NICETOHAVE_DONE: ${{ steps.progress.outputs.nicetohave_done }}
|
||||
NICETOHAVE_TOTAL: ${{ steps.progress.outputs.nicetohave_total }}
|
||||
VERSION: ${{ steps.progress.outputs.version }}
|
||||
run: |
|
||||
# Execute dedicated badge generation script
|
||||
# This separates concerns: YAML orchestrates, scripts implement logic
|
||||
bash .github/workflows/update-badge.sh
|
||||
|
||||
- name: Cleanup on failure
|
||||
|
||||
- name: Update failure badge on error
|
||||
if: failure()
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GIST_TOKEN }}
|
||||
GIST_ID: ${{ secrets.GIST_ID }}
|
||||
run: |
|
||||
echo "::warning::Workflow failed - cleaning up temporary files"
|
||||
rm -f progress_output.txt
|
||||
echo "::notice::Check the logs above for specific error details"
|
||||
echo "::warning::Workflow failed - updating badges to FAILURE state"
|
||||
|
||||
REPO_NAME="${GITHUB_REPOSITORY##*/}"
|
||||
BLOCKER_GIST_NAME="release-blocker-${REPO_NAME}.json"
|
||||
MUSTDO_GIST_NAME="release-mustdo-${REPO_NAME}.json"
|
||||
|
||||
FAILURE_BADGE=$(jq -n '{
|
||||
"schemaVersion": 1,
|
||||
"label": "Release Progress",
|
||||
"message": "FAILURE",
|
||||
"color": "BF00FF",
|
||||
"style": "flat-square"
|
||||
}')
|
||||
|
||||
REQUEST_PAYLOAD=$(jq -n \
|
||||
--arg blocker_filename "$BLOCKER_GIST_NAME" \
|
||||
--arg mustdo_filename "$MUSTDO_GIST_NAME" \
|
||||
--argjson content "$FAILURE_BADGE" \
|
||||
'{
|
||||
"files": {
|
||||
($blocker_filename): { "content": ($content | tostring) },
|
||||
($mustdo_filename): { "content": ($content | tostring) }
|
||||
}
|
||||
}')
|
||||
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -L -X PATCH \
|
||||
-H "Authorization: token ${GITHUB_TOKEN}" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
"https://api.github.com/gists/${GIST_ID}" \
|
||||
-d "$REQUEST_PAYLOAD")
|
||||
|
||||
if [ "$HTTP_CODE" != "200" ]; then
|
||||
echo "::warning::Failed to update failure badges (HTTP $HTTP_CODE)"
|
||||
else
|
||||
echo "::notice::Failure badges updated successfully"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user