Skip to content

Commit 891065d

Browse files
feat(workflows): add issue lifecycle with update mechanism (#98)
## Summary - Rename label `sub-issue` → `plot-request:impl` for clarity - Add update mechanism via `[update]` and `[update:library]` title syntax - Add targeted library regeneration (skip unaffected libraries) - Add new labels: `test`, `update`, `completed` - Document lifecycle and update workflow ## Changes ### New Update Syntax - `[update] scatter-basic` → Regenerate all 8 libraries - `[update:seaborn] scatter-basic` → Regenerate only seaborn - Issue body can contain spec changes (Claude updates spec first) ### Issue Lifecycle ``` [open] plot-request → approved → in-progress → completed [closed] ``` ### New Labels - `test` - Test issues excluded from production searches - `update` - Update request for existing spec - `completed` - All implementations merged ### Files Changed - `.github/workflows/gen-new-plot.yml` - Update detection + targeted generation - `.github/workflows/bot-sync-status.yml` - Label rename - `.github/ISSUE_TEMPLATE/plot-update.yml` - New syntax + library dropdown - `CLAUDE.md` - Labels + lifecycle documentation - `docs/workflow.md` - Labels + update workflow documentation ## Test plan - [ ] Create `[update] line-basic` issue and verify only generation jobs run - [ ] Create `[update:matplotlib] line-basic` and verify only matplotlib job runs - [ ] Verify test label excludes issues from `is:issue label:plot-request -label:test` search
1 parent bff433c commit 891065d

6 files changed

Lines changed: 191 additions & 47 deletions

File tree

.github/ISSUE_TEMPLATE/plot-update.yml

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,73 @@
11
name: Plot Update
2-
description: Request changes or improvements to an existing plot
3-
title: "Update: "
4-
labels: ["plot-update"]
2+
description: Request updates or regeneration of an existing plot
3+
title: "[update] "
4+
labels: ["plot-request", "update"]
55
body:
66
- type: markdown
77
attributes:
88
value: |
99
## Plot Update Request
1010
11-
Use this form to request changes to an existing plot implementation.
12-
This will be linked as a sub-issue to the original plot request.
11+
Use this form to update or regenerate an existing plot.
1312
14-
- type: input
15-
id: parent_issue
16-
attributes:
17-
label: Original Plot Request
18-
description: "Issue number of the original plot-request (e.g., #24)"
19-
placeholder: "#24"
20-
validations:
21-
required: true
13+
**Title Format:**
14+
- `[update] scatter-basic` → Regenerate all 8 libraries
15+
- `[update:seaborn] scatter-basic` → Regenerate only seaborn
16+
17+
After submitting, a maintainer will add the `approved` label to trigger regeneration.
2218
2319
- type: input
2420
id: spec_id
2521
attributes:
2622
label: Spec ID
27-
description: "The spec ID of the plot to update (e.g., bar-basic)"
28-
placeholder: "bar-basic"
23+
description: "The spec ID of the plot to update (will be appended to title)"
24+
placeholder: "scatter-basic"
2925
validations:
3026
required: true
3127

28+
- type: dropdown
29+
id: target_library
30+
attributes:
31+
label: Target Library (optional)
32+
description: Update only a specific library, or leave empty for all
33+
options:
34+
- All libraries
35+
- matplotlib
36+
- seaborn
37+
- plotly
38+
- bokeh
39+
- altair
40+
- plotnine
41+
- pygal
42+
- highcharts
43+
validations:
44+
required: false
45+
3246
- type: dropdown
3347
id: update_type
3448
attributes:
3549
label: Type of Update
3650
description: What kind of change is this?
3751
options:
52+
- Regenerate (use current spec)
53+
- Spec Update (describe changes below)
3854
- Bug Fix (plot doesn't render correctly)
3955
- Visual Improvement (styling, colors, layout)
4056
- Feature Addition (new parameter, option)
41-
- Performance (faster rendering, less memory)
42-
- Code Quality (refactoring, better practices)
43-
- Documentation (docstrings, comments)
4457
validations:
4558
required: true
4659

4760
- type: textarea
48-
id: current_behavior
61+
id: changes
4962
attributes:
50-
label: Current Behavior
51-
description: Describe what the plot currently does
52-
placeholder: "The bar chart currently shows labels overlapping when there are many categories..."
63+
label: Requested Changes
64+
description: Describe the changes to the spec or implementation (Claude will update the spec first if needed)
65+
placeholder: |
66+
- Add grid lines for better readability
67+
- Change default color scheme to colorblind-friendly
68+
- Include legend for all data series
5369
validations:
54-
required: true
55-
56-
- type: textarea
57-
id: desired_behavior
58-
attributes:
59-
label: Desired Behavior
60-
description: Describe what you want the plot to do instead
61-
placeholder: "Labels should be rotated 45 degrees to prevent overlap, or use a horizontal layout..."
62-
validations:
63-
required: true
70+
required: false
6471

6572
- type: textarea
6673
id: additional_context

.github/copilot-instructions.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,41 @@ Examples: `scatter-basic`, `scatter-color-mapped`, `bar-grouped-horizontal`, `he
7777
- **`tests/unit/`**: Unit tests mirroring source structure
7878
- **`docs/`**: Architecture and workflow documentation
7979

80+
## GitHub Issue Labels
81+
82+
### Workflow Status Labels
83+
84+
- **`plot-request`** - Main plot request issue
85+
- **`plot-request:impl`** - Library implementation sub-issue (child of main)
86+
- **`generating`** - Code is being generated
87+
- **`testing`** - Tests are running
88+
- **`reviewing`** - Quality review in progress
89+
- **`merged`** - Successfully merged to main
90+
- **`not-feasible`** - 3x failed, not implementable in this library
91+
- **`completed`** - All library implementations complete
92+
- **`update`** - Update request for existing spec
93+
- **`test`** - Test issue, not a real plot request
94+
95+
### Updating Existing Plots
96+
97+
To update an existing plot:
98+
1. Create issue with title: `[update] {spec-id}` (all libraries) or `[update:library] {spec-id}` (single library)
99+
2. Add label: `plot-request`
100+
3. Issue body can contain spec changes (Claude updates spec first)
101+
4. Maintainer adds `approved` label
102+
5. Workflow regenerates specified implementations
103+
104+
**Issue Lifecycle:**
105+
```
106+
[open] plot-request → approved → in-progress → completed [closed]
107+
```
108+
109+
**Sub-Issue Lifecycle:**
110+
```
111+
[open] generating → testing → reviewing → merged [closed]
112+
→ not-feasible [closed]
113+
```
114+
80115
## Code Standards
81116

82117
### Python Style

.github/workflows/bot-sync-status.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ jobs:
3333
ISSUE_NUM="${{ github.event.issue.number }}"
3434
LABELS="${{ join(github.event.issue.labels.*.name, ',') }}"
3535
36-
# Check if this is a sub-issue
37-
if echo "$LABELS" | grep -q "sub-issue"; then
36+
# Check if this is a plot-request implementation issue
37+
if echo "$LABELS" | grep -q "plot-request:impl"; then
3838
# Find parent from issue body
3939
BODY=$(gh issue view $ISSUE_NUM --json body -q '.body')
4040
PARENT_NUM=$(echo "$BODY" | grep -oP '\*\*Parent Issue:\*\* #\K\d+' | head -1 || echo "")

.github/workflows/gen-new-plot.yml

Lines changed: 69 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ jobs:
2121
outputs:
2222
should_run: ${{ steps.check.outputs.should_run }}
2323
spec_id: ${{ steps.extract_spec.outputs.spec_id }}
24+
is_update: ${{ steps.extract_spec.outputs.is_update }}
25+
target_library: ${{ steps.extract_spec.outputs.target_library }}
2426

2527
steps:
2628
- name: Check conditions
@@ -63,6 +65,29 @@ jobs:
6365
ISSUE_BODY: ${{ github.event.issue.body }}
6466
ISSUE_TITLE: ${{ github.event.issue.title }}
6567
run: |
68+
# Check for [update] or [update:library] prefix in title
69+
IS_UPDATE="false"
70+
TARGET_LIBRARY=""
71+
72+
if echo "$ISSUE_TITLE" | grep -qiP '^\[update(:[a-z]+)?\]'; then
73+
IS_UPDATE="true"
74+
# Extract target library if specified (e.g., [update:seaborn])
75+
TARGET_LIBRARY=$(echo "$ISSUE_TITLE" | grep -oiP '^\[update:\K[a-z]+(?=\])' | tr '[:upper:]' '[:lower:]' || echo "")
76+
# Remove [update...] prefix from title for spec ID extraction
77+
CLEAN_TITLE=$(echo "$ISSUE_TITLE" | sed 's/^\[update[^]]*\]\s*//')
78+
echo "::notice::Update mode detected. Target library: ${TARGET_LIBRARY:-all}"
79+
else
80+
CLEAN_TITLE="$ISSUE_TITLE"
81+
fi
82+
83+
# Validate TARGET_LIBRARY if specified
84+
if [ -n "$TARGET_LIBRARY" ]; then
85+
VALID_LIBS="matplotlib seaborn plotly bokeh altair plotnine pygal highcharts"
86+
if ! echo "$VALID_LIBS" | grep -qw "$TARGET_LIBRARY"; then
87+
echo "::error::Invalid library '$TARGET_LIBRARY'. Must be one of: $VALID_LIBS"
88+
exit 1
89+
fi
90+
fi
6691
# Check if issue was marked as duplicate
6792
COMMENTS=$(gh issue view ${{ github.event.issue.number }} --json comments -q '.comments[].body')
6893
@@ -71,8 +96,15 @@ jobs:
7196
exit 1
7297
fi
7398
99+
# For updates, try to extract spec ID from cleaned title first
100+
if [ "$IS_UPDATE" == "true" ]; then
101+
SPEC_ID=$(echo "$CLEAN_TITLE" | grep -oiP '^[a-z]+-[a-z]+(-[a-z0-9]+)?' | tr '[:upper:]' '[:lower:]' || echo "")
102+
fi
103+
74104
# Extract spec ID from issue comments (assigned by validate-plot-request workflow)
75-
SPEC_ID=$(echo "$COMMENTS" | grep -oP '\*\*Assigned ID:\*\* `\K[a-z0-9-]+(?=`)' | tail -1 || echo "")
105+
if [ -z "$SPEC_ID" ]; then
106+
SPEC_ID=$(echo "$COMMENTS" | grep -oP '\*\*Assigned ID:\*\* `\K[a-z0-9-]+(?=`)' | tail -1 || echo "")
107+
fi
76108
77109
if [ -z "$SPEC_ID" ]; then
78110
SPEC_ID=$(echo "$COMMENTS" | grep -oP '\*\*Existing Spec:\*\* `\K[a-z0-9-]+(?=`)' | tail -1 || echo "")
@@ -92,7 +124,9 @@ jobs:
92124
fi
93125
94126
echo "spec_id=$SPEC_ID" >> $GITHUB_OUTPUT
95-
echo "::notice::Extracted spec ID: $SPEC_ID"
127+
echo "is_update=$IS_UPDATE" >> $GITHUB_OUTPUT
128+
echo "target_library=$TARGET_LIBRARY" >> $GITHUB_OUTPUT
129+
echo "::notice::Extracted spec ID: $SPEC_ID (update=$IS_UPDATE, target=$TARGET_LIBRARY)"
96130
97131
# ============================================================================
98132
# Step 2: Create sub-issues for each library
@@ -169,7 +203,7 @@ jobs:
169203
SUB_ISSUE=$(gh issue create \
170204
--title "[$SPEC_ID] $LIBRARY implementation" \
171205
--body "$SUB_BODY" \
172-
--label "library:$LIBRARY,sub-issue,generating")
206+
--label "library:$LIBRARY,plot-request:impl,generating")
173207
174208
SUB_NUM=$(echo "$SUB_ISSUE" | grep -oP '\d+$')
175209
SUB_NODE_ID=$(gh api repos/${{ github.repository }}/issues/$SUB_NUM --jq '.node_id')
@@ -191,7 +225,10 @@ jobs:
191225
# ============================================================================
192226
generate-matplotlib:
193227
needs: [check-conditions, create-sub-issues]
194-
if: needs.check-conditions.outputs.should_run == 'true'
228+
if: |
229+
needs.check-conditions.outputs.should_run == 'true' &&
230+
(needs.check-conditions.outputs.target_library == '' ||
231+
needs.check-conditions.outputs.target_library == 'matplotlib')
195232
uses: ./.github/workflows/gen-library-impl.yml
196233
with:
197234
spec_id: ${{ needs.check-conditions.outputs.spec_id }}
@@ -204,7 +241,10 @@ jobs:
204241

205242
generate-seaborn:
206243
needs: [check-conditions, create-sub-issues]
207-
if: needs.check-conditions.outputs.should_run == 'true'
244+
if: |
245+
needs.check-conditions.outputs.should_run == 'true' &&
246+
(needs.check-conditions.outputs.target_library == '' ||
247+
needs.check-conditions.outputs.target_library == 'seaborn')
208248
uses: ./.github/workflows/gen-library-impl.yml
209249
with:
210250
spec_id: ${{ needs.check-conditions.outputs.spec_id }}
@@ -217,7 +257,10 @@ jobs:
217257

218258
generate-plotly:
219259
needs: [check-conditions, create-sub-issues]
220-
if: needs.check-conditions.outputs.should_run == 'true'
260+
if: |
261+
needs.check-conditions.outputs.should_run == 'true' &&
262+
(needs.check-conditions.outputs.target_library == '' ||
263+
needs.check-conditions.outputs.target_library == 'plotly')
221264
uses: ./.github/workflows/gen-library-impl.yml
222265
with:
223266
spec_id: ${{ needs.check-conditions.outputs.spec_id }}
@@ -230,7 +273,10 @@ jobs:
230273

231274
generate-bokeh:
232275
needs: [check-conditions, create-sub-issues]
233-
if: needs.check-conditions.outputs.should_run == 'true'
276+
if: |
277+
needs.check-conditions.outputs.should_run == 'true' &&
278+
(needs.check-conditions.outputs.target_library == '' ||
279+
needs.check-conditions.outputs.target_library == 'bokeh')
234280
uses: ./.github/workflows/gen-library-impl.yml
235281
with:
236282
spec_id: ${{ needs.check-conditions.outputs.spec_id }}
@@ -243,7 +289,10 @@ jobs:
243289

244290
generate-altair:
245291
needs: [check-conditions, create-sub-issues]
246-
if: needs.check-conditions.outputs.should_run == 'true'
292+
if: |
293+
needs.check-conditions.outputs.should_run == 'true' &&
294+
(needs.check-conditions.outputs.target_library == '' ||
295+
needs.check-conditions.outputs.target_library == 'altair')
247296
uses: ./.github/workflows/gen-library-impl.yml
248297
with:
249298
spec_id: ${{ needs.check-conditions.outputs.spec_id }}
@@ -256,7 +305,10 @@ jobs:
256305

257306
generate-plotnine:
258307
needs: [check-conditions, create-sub-issues]
259-
if: needs.check-conditions.outputs.should_run == 'true'
308+
if: |
309+
needs.check-conditions.outputs.should_run == 'true' &&
310+
(needs.check-conditions.outputs.target_library == '' ||
311+
needs.check-conditions.outputs.target_library == 'plotnine')
260312
uses: ./.github/workflows/gen-library-impl.yml
261313
with:
262314
spec_id: ${{ needs.check-conditions.outputs.spec_id }}
@@ -269,7 +321,10 @@ jobs:
269321

270322
generate-pygal:
271323
needs: [check-conditions, create-sub-issues]
272-
if: needs.check-conditions.outputs.should_run == 'true'
324+
if: |
325+
needs.check-conditions.outputs.should_run == 'true' &&
326+
(needs.check-conditions.outputs.target_library == '' ||
327+
needs.check-conditions.outputs.target_library == 'pygal')
273328
uses: ./.github/workflows/gen-library-impl.yml
274329
with:
275330
spec_id: ${{ needs.check-conditions.outputs.spec_id }}
@@ -282,7 +337,10 @@ jobs:
282337

283338
generate-highcharts:
284339
needs: [check-conditions, create-sub-issues]
285-
if: needs.check-conditions.outputs.should_run == 'true'
340+
if: |
341+
needs.check-conditions.outputs.should_run == 'true' &&
342+
(needs.check-conditions.outputs.target_library == '' ||
343+
needs.check-conditions.outputs.target_library == 'highcharts')
286344
uses: ./.github/workflows/gen-library-impl.yml
287345
with:
288346
spec_id: ${{ needs.check-conditions.outputs.spec_id }}

CLAUDE.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,13 +339,15 @@ bash .github/scripts/setup-labels.sh
339339

340340
### Workflow Status Labels
341341

342-
- **`sub-issue`** - Library-specific sub-issue (child of main plot-request)
342+
- **`plot-request:impl`** - Library implementation sub-issue (child of main plot-request)
343343
- **`generating`** - Code is being generated
344344
- **`testing`** - Tests are running
345345
- **`reviewing`** - Quality review in progress
346346
- **`merged`** - Successfully merged to main
347347
- **`not-feasible`** - 3x failed, not implementable in this library
348348
- **`completed`** - All library implementations complete
349+
- **`update`** - Update request for existing spec (use with plot-request)
350+
- **`test`** - Test issue, not a real plot request
349351

350352
### Approval Labels (Human vs AI distinction)
351353

@@ -399,6 +401,31 @@ bash .github/scripts/setup-labels.sh
399401
- Partial success (5/8 can merge while 3/8 retry)
400402
- Per-library dependency isolation
401403

404+
### Updating Existing Plots
405+
406+
To update an existing plot implementation:
407+
408+
1. Create issue with title: `[update] {spec-id}` (all libraries) or `[update:{library}] {spec-id}` (single library)
409+
- Example: `[update] scatter-basic` - regenerate all 8 libraries
410+
- Example: `[update:seaborn] scatter-basic` - regenerate only seaborn
411+
2. Add label: `plot-request`
412+
3. Issue body can contain spec changes (Claude will update `specs/{spec-id}.md` first)
413+
4. Maintainer adds `approved` label
414+
5. Workflow regenerates specified implementations
415+
416+
**Issue Lifecycle:**
417+
```
418+
[open] plot-request → approved → in-progress → completed [closed]
419+
```
420+
421+
**Sub-Issue Lifecycle:**
422+
```
423+
[open] generating → testing → reviewing → merged [closed]
424+
→ not-feasible [closed]
425+
```
426+
427+
**Test Issues:** When creating issues for testing workflows, add the `test` label to exclude them from production searches.
428+
402429
## Environment Variables
403430
404431
Required in `.env`:

0 commit comments

Comments
 (0)