Skip to content

feat(bokeh): implement line-basic #931

feat(bokeh): implement line-basic

feat(bokeh): implement line-basic #931

Workflow file for this run

name: "Bot: Sync Sub-Issue Status"
# Syncs the status of all library sub-issues to the main issue's status table
on:
issues:
types: [labeled, unlabeled, closed]
pull_request:
types: [labeled, closed]
workflow_run:
workflows: ["Gen: Library Implementation", "Bot: AI Review"]
types: [completed]
jobs:
sync-status:
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
pull-requests: read
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Determine parent issue
id: parent
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Try to find parent issue from different trigger types
if [ "${{ github.event_name }}" == "issues" ]; then
ISSUE_NUM="${{ github.event.issue.number }}"
LABELS="${{ join(github.event.issue.labels.*.name, ',') }}"
# Check if this is a plot-request implementation issue
if echo "$LABELS" | grep -q "plot-request:impl"; then
# Find parent from issue body
BODY=$(gh issue view $ISSUE_NUM --json body -q '.body')
PARENT_NUM=$(echo "$BODY" | grep -oP '\*\*Parent Issue:\*\* #\K\d+' | head -1 || echo "")
if [ -n "$PARENT_NUM" ]; then
echo "parent_number=$PARENT_NUM" >> $GITHUB_OUTPUT
echo "should_sync=true" >> $GITHUB_OUTPUT
exit 0
fi
fi
# Check if this is the main issue with plot-request label
if echo "$LABELS" | grep -q "plot-request"; then
echo "parent_number=$ISSUE_NUM" >> $GITHUB_OUTPUT
echo "should_sync=true" >> $GITHUB_OUTPUT
exit 0
fi
elif [ "${{ github.event_name }}" == "pull_request" ]; then
PR_NUM="${{ github.event.pull_request.number }}"
# Safely get PR body using gh CLI to avoid shell escaping issues with newlines
PR_BODY=$(gh pr view "$PR_NUM" --json body -q '.body' 2>/dev/null || echo "")
# Extract parent issue from PR body
PARENT_NUM=$(echo "$PR_BODY" | grep -oP '\*\*Parent Issue:\*\* #\K\d+' | head -1 || echo "")
if [ -n "$PARENT_NUM" ]; then
echo "parent_number=$PARENT_NUM" >> $GITHUB_OUTPUT
echo "should_sync=true" >> $GITHUB_OUTPUT
exit 0
fi
elif [ "${{ github.event_name }}" == "workflow_run" ]; then
# For workflow_run, we need to extract from artifacts or run context
# This is a fallback - the main triggers should handle most cases
echo "should_sync=false" >> $GITHUB_OUTPUT
exit 0
fi
echo "should_sync=false" >> $GITHUB_OUTPUT
- name: Collect sub-issue statuses
if: steps.parent.outputs.should_sync == 'true'
id: collect
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PARENT_NUM: ${{ steps.parent.outputs.parent_number }}
run: |
# Get all sub-issues for this parent
# Using GitHub's sub-issues API or searching for issues with "Parent Issue: #N" in body
SUB_ISSUES=$(gh api graphql -f query='
query($owner: String!, $repo: String!, $parent: Int!) {
repository(owner: $owner, name: $repo) {
issue(number: $parent) {
subIssues(first: 20) {
nodes {
number
title
labels(first: 10) {
nodes { name }
}
state
}
}
}
}
}' -f owner="${{ github.repository_owner }}" -f repo="${{ github.event.repository.name }}" -F parent="$PARENT_NUM" 2>/dev/null || echo '{"data":{"repository":{"issue":{"subIssues":{"nodes":[]}}}}}')
# Fallback: search for issues with "Parent Issue: #N" in body
if [ "$(echo "$SUB_ISSUES" | jq '.data.repository.issue.subIssues.nodes | length')" == "0" ]; then
SUB_ISSUES_SEARCH=$(gh issue list --search "**Parent Issue:** #$PARENT_NUM in:body" --json number,title,labels,state)
echo "$SUB_ISSUES_SEARCH" > /tmp/sub_issues.json
else
echo "$SUB_ISSUES" | jq '.data.repository.issue.subIssues.nodes' > /tmp/sub_issues.json
fi
echo "sub_issues_file=/tmp/sub_issues.json" >> $GITHUB_OUTPUT
- name: Build status table
if: steps.parent.outputs.should_sync == 'true'
id: table
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PARENT_NUM: ${{ steps.parent.outputs.parent_number }}
run: |
# Define all libraries
LIBRARIES="matplotlib seaborn plotly bokeh altair plotnine pygal highcharts"
# Start building the table
cat > /tmp/status_table.md << 'TABLEEOF'
## Implementation Status
| Library | Status | Score | PR | Attempts |
|---------|--------|-------|-----|----------|
TABLEEOF
for LIB in $LIBRARIES; do
# Find sub-issue for this library
SUB_ISSUE=$(jq -r --arg lib "$LIB" '.[] | select(.title | contains($lib)) | .number' /tmp/sub_issues.json 2>/dev/null | head -1 || echo "")
if [ -z "$SUB_ISSUE" ]; then
# No sub-issue yet
echo "| $LIB | :hourglass: Pending | - | - | 0/3 |" >> /tmp/status_table.md
continue
fi
# Get labels for status
LABELS=$(jq -r --arg lib "$LIB" '.[] | select(.title | contains($lib)) | .labels | if type == "array" then .[].name else .nodes[].name end' /tmp/sub_issues.json 2>/dev/null | tr '\n' ',' || echo "")
# Determine status emoji and text
if echo "$LABELS" | grep -q "merged"; then
STATUS=":white_check_mark: Merged"
elif echo "$LABELS" | grep -q "ai-approved"; then
STATUS=":ballot_box_with_check: Approved"
elif echo "$LABELS" | grep -q "not-feasible"; then
STATUS=":warning: Not Feasible"
elif echo "$LABELS" | grep -q "ai-rejected"; then
STATUS=":x: Rejected"
elif echo "$LABELS" | grep -q "reviewing"; then
STATUS=":mag: Reviewing"
elif echo "$LABELS" | grep -q "testing"; then
STATUS=":test_tube: Testing"
elif echo "$LABELS" | grep -q "generating"; then
STATUS=":gear: Generating"
else
STATUS=":hourglass: Pending"
fi
# Get quality score from sub-issue comments (format: | Claude | XX/100 | approve |)
SCORE=$(gh api repos/${{ github.repository }}/issues/$SUB_ISSUE/comments \
--jq '[.[] | .body | capture("Claude \\| (?<score>\\d+)/100") | .score] | last // "-"' 2>/dev/null || echo "-")
# Find PR for this library (search by library name in auto/ branches)
PR_NUM=$(gh pr list --head "auto/" --search "$LIB" \
--json number,headRefName -q '.[] | select(.headRefName | contains("'"$LIB"'")) | .number' 2>/dev/null | head -1 || echo "")
PR_LINK=$([[ -n "$PR_NUM" ]] && echo "#$PR_NUM" || echo "-")
# Count attempts from sub-issue comments
ATTEMPTS=$(gh api repos/${{ github.repository }}/issues/$SUB_ISSUE/comments \
--jq '[.[] | .body | select(startswith("## Attempt"))] | length' 2>/dev/null || echo "0")
[[ -z "$ATTEMPTS" ]] && ATTEMPTS=0
echo "| $LIB | $STATUS | $SCORE | $PR_LINK | $ATTEMPTS/3 |" >> /tmp/status_table.md
done
echo "" >> /tmp/status_table.md
echo "_Last updated: $(date -u +"%Y-%m-%d %H:%M UTC")_" >> /tmp/status_table.md
cat /tmp/status_table.md
- name: Update main issue body
if: steps.parent.outputs.should_sync == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PARENT_NUM: ${{ steps.parent.outputs.parent_number }}
run: |
# Get current issue body
CURRENT_BODY=$(gh issue view $PARENT_NUM --json body -q '.body')
# Check if status table already exists
if echo "$CURRENT_BODY" | grep -q "## Implementation Status"; then
# Replace existing table
# Find start and end markers
NEW_BODY=$(echo "$CURRENT_BODY" | awk '
/^## Implementation Status/ { skip=1; next }
/^## / && skip { skip=0 }
!skip { print }
')
# Append new table at the end
echo "$NEW_BODY" > /tmp/new_body.md
echo "" >> /tmp/new_body.md
cat /tmp/status_table.md >> /tmp/new_body.md
else
# Append table to existing body
echo "$CURRENT_BODY" > /tmp/new_body.md
echo "" >> /tmp/new_body.md
cat /tmp/status_table.md >> /tmp/new_body.md
fi
# Update issue
gh issue edit $PARENT_NUM --body-file /tmp/new_body.md
echo "::notice::Updated status table in issue #$PARENT_NUM"