Skip to content

Create test issue and merge via GitHub#6

Merged
MarkusNeusinger merged 2 commits intomainfrom
claude/create-test-issue-merge-01D6cfGXen5SRMqh8Xgf7iUn
Nov 24, 2025
Merged

Create test issue and merge via GitHub#6
MarkusNeusinger merged 2 commits intomainfrom
claude/create-test-issue-merge-01D6cfGXen5SRMqh8Xgf7iUn

Conversation

@MarkusNeusinger
Copy link
Copy Markdown
Owner

Remove issue opening trigger from claude.yml to avoid conflicts with spec-to-code.yml workflow. Now Claude Code only triggers on comments, enabling clean approved workflow:

  1. Create issue without @claude
  2. Add 'approved' label
  3. spec-to-code.yml posts @claude comment
  4. claude.yml triggers on comment (not on issue opening)

This prevents the issue where Claude Code would trigger twice for the same issue and ignore the second trigger.

Remove issue opening trigger from claude.yml to avoid conflicts with
spec-to-code.yml workflow. Now Claude Code only triggers on comments,
enabling clean approved workflow:

1. Create issue without @claude
2. Add 'approved' label
3. spec-to-code.yml posts @claude comment
4. claude.yml triggers on comment (not on issue opening)

This prevents the issue where Claude Code would trigger twice for the
same issue and ignore the second trigger.
@claude
Copy link
Copy Markdown
Contributor

claude bot commented Nov 24, 2025

Code Review: Workflow Trigger Cleanup

Summary

This PR removes the issues event trigger from claude.yml to prevent duplicate Claude Code invocations. The change is well-reasoned and correctly implemented.


Strengths

  1. Solves a Real Problem: Prevents the race condition where:

    • Issue is created with @claude in body/title → claude.yml triggers
    • Issue gets approved label → spec-to-code.yml posts @claude comment → claude.yml triggers again
    • Result: Duplicate work and wasted resources
  2. Clean Workflow Separation:

    • spec-to-code.yml: Orchestrates the approval → code generation flow
    • claude.yml: Responds only to explicit @claude mentions in comments/reviews
    • This separation follows the Single Responsibility Principle
  3. Minimal Impact: Only 5 lines changed, reducing complexity without affecting other functionality

  4. Proper Conditional Logic: The remaining conditions in claude.yml:13-16 are clean and maintain backward compatibility for PR review comments


📋 Code Quality Assessment

Best Practices: ✅ Excellent

  • Follows GitHub Actions best practices
  • Maintains consistent trigger patterns
  • Clear conditional logic

Potential Bugs: ✅ None identified

  • The change is safe and doesn't introduce new edge cases
  • All remaining triggers are properly scoped

Performance: ✅ Improved

  • Eliminates unnecessary workflow runs
  • Reduces GitHub Actions minutes consumption
  • Prevents duplicate Claude Code sessions

Security: ✅ No concerns

  • No security implications
  • Maintains proper permission scoping in claude.yml:18-23

🔍 Detailed Analysis

Before (Problems)

on:
  issues:
    types: [opened, assigned]  # ⚠️ Could trigger twice for same issue

Scenario:

  1. User creates issue with title: "scatter-basic-001: New plot"
  2. If body contains @claudeclaude.yml triggers immediately
  3. Maintainer adds approved label → spec-to-code.yml posts @claude comment
  4. Comment triggers claude.yml again → Duplicate work

After (Fixed)

on:
  issue_comment:
    types: [created]  # ✅ Only responds to comments

New Flow:

  1. User creates issue (no @claude needed)
  2. Maintainer adds approved label
  3. spec-to-code.yml posts structured @claude comment with instructions
  4. claude.yml triggers once with proper context

🎯 Recommendations

1. Update Documentation (Optional but Recommended)

The change alters the workflow described in docs/architecture/automation-workflows.md:662. Consider updating:

# Before
Person->>Issues: Create issue with @claude
Issues->>GHA: Trigger claude.yml

# After  
Person->>Issues: Create issue (no @claude needed)
Person->>Issues: Add label "approved"
Issues->>GHA: Trigger spec-to-code.yml
GHA->>Issues: Post @claude comment
Issues->>GHA: Trigger claude.yml

2. Consider Adding Workflow Dispatch (Future Enhancement)

For debugging/testing, you might want to add manual trigger capability:

on:
  workflow_dispatch:
    inputs:
      issue_number:
        description: 'Issue number to process'
        required: true

This would allow manual testing without creating real issues.

3. Test Coverage

Since this is a workflow configuration change, consider testing:

  • ✅ Create issue without @claude → No trigger (expected)
  • ✅ Add approved label → spec-to-code.yml runs → Claude Code triggers via comment
  • ✅ Manual @claude comment on existing issue → Claude Code responds

📊 Test Coverage

N/A - GitHub Actions workflow configuration (no unit tests applicable)
Validation: Should be tested in staging/development environment before production deployment


🎉 Verdict

APPROVED

This is a clean, focused fix that:

  • Eliminates a documented workflow conflict
  • Improves resource efficiency
  • Maintains all existing functionality
  • Follows the principle of least surprise

The PR description clearly explains the problem and solution. The implementation is correct and minimal.


💡 Minor Suggestions

  1. PR Title Enhancement: Consider more descriptive title:

    • Current: "Create test issue and merge via GitHub"
    • Suggested: "fix: remove duplicate claude.yml trigger on issue creation"
  2. Commit Message: Ensure commit message follows conventional commits:

    fix(workflows): prevent duplicate Claude Code triggers on issue creation
    
    Remove 'issues' event trigger from claude.yml to avoid conflicts with
    spec-to-code.yml workflow. Claude Code now only triggers on comments,
    enabling clean approved workflow without duplicate invocations.
    
    Resolves race condition where Claude would trigger twice for the same
    issue when both issue body contained @claude and approval label was added.
    

Great work on identifying and fixing this workflow conflict! 🚀

Updated spec-to-code and quality-check workflow documentation to show
the new implementation using Claude Code Action instead of direct API calls.

Changes:
- spec-to-code.yml now posts @claude comment instead of calling API
- quality-check.yml now posts @claude comment instead of calling API
- claude.yml executes both workflows via anthropics/claude-code-action
- Added note about live visibility in Claude Code Web
- Added CLAUDE_CODE_OAUTH_TOKEN requirement

This reflects the actual implementation after the refactoring to make
workflows visible and trackable in Claude Code Web.
@MarkusNeusinger MarkusNeusinger merged commit fe8ff5f into main Nov 24, 2025
1 check passed
@MarkusNeusinger MarkusNeusinger deleted the claude/create-test-issue-merge-01D6cfGXen5SRMqh8Xgf7iUn branch November 24, 2025 13:17
@claude
Copy link
Copy Markdown
Contributor

claude bot commented Nov 24, 2025

Code Review - PR #6

Overview

This PR removes the issues: [opened, assigned] trigger from claude.yml to prevent double-triggering of Claude Code. The change establishes a cleaner workflow where spec-to-code.yml orchestrates code generation by posting a @claude comment, which then triggers claude.yml.

✅ Strengths

  1. Addresses a Real Race Condition

    • Prevents duplicate Claude Code invocations on the same issue
    • Establishes clear separation of concerns: spec-to-code.yml = trigger, claude.yml = executor
  2. Documentation Excellence

    • Comprehensive documentation updates in automation-workflows.md
    • Clear explanation of the two-step workflow
    • Includes YAML examples and expected outcomes
    • Documents required secrets
  3. Follows Project Standards

    • Aligns with the project's automation-first philosophy
    • Maintains the "approved workflow" pattern from CLAUDE.md

🔍 Observations & Recommendations

1. Workflow Trigger Logic (.github/workflows/claude.yml:13-16)

The conditional logic is clean and well-structured:

if: |
  (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
  (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
  (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude'))

Consideration: The contains() check is case-sensitive. Should @Claude or @CLAUDE also trigger the workflow? If so, consider using contains(lower(), '@claude') (though GitHub Actions doesn't support lower() directly, you'd need a workaround).

Current behavior is probably correct - requiring exact @claude mention maintains consistency and prevents accidental triggers.

2. Edge Case: Manual Issue Creation with @claude

With the removal of issues: [opened, assigned] triggers, the workflow now requires:

  1. Create issue without @claude
  2. Add approved label
  3. spec-to-code.yml posts @claude comment
  4. claude.yml triggers on comment

Potential edge case: What if someone manually creates an issue with @claude in the body AND the approved label?

  • Before this PR: Would trigger twice (issue opened + spec-to-code comment)
  • After this PR: Only triggers once (spec-to-code comment) ✅

This is the correct behavior and the PR solves it properly.

3. Documentation Accuracy (docs/architecture/automation-workflows.md:55-58)

The documentation states:

1. **spec-to-code.yml** (trigger workflow):
   - Extracts spec ID from issue title (format: `scatter-basic-001`)
   - Posts `@claude` comment with detailed generation instructions
   - Links to spec file, generation rules, and quality criteria

This is accurate based on spec-to-code.yml:16-44 which does extract spec ID and post @claude comment.

4. Missing Error Handling Documentation

The workflow file spec-to-code.yml:32-41 handles errors when spec files don't exist, but the documentation doesn't mention this failure mode. Consider adding to docs:

**Error Handling**:
- If spec ID cannot be extracted → workflow fails with helpful error message
- If spec file doesn't exist → warning posted, but workflow continues (allows Claude to create the spec from issue body)

5. Security Considerations

The workflow permissions are appropriately scoped:

permissions:
  contents: write        # Allow commits
  pull-requests: write   # Allow PR creation
  issues: write         # Allow issue comments
  id-token: write
  actions: read         # Required for Claude to read CI results

No security concerns identified.

6. Quality Check Workflow Documentation

The documentation also updates the quality-check workflow to follow the same pattern (docs/architecture/automation-workflows.md:193-216). This is good for consistency, but I don't see the corresponding quality-check.yml changes in this PR.

Question: Is quality-check.yml already implemented with this pattern, or is that a future change? If future, consider adding a note in the docs indicating the quality-check section describes the planned workflow.

🐛 Potential Issues

None identified - The code changes are minimal, focused, and solve the stated problem.

⚡ Performance Considerations

Positive impact: By eliminating double-triggers, this reduces:

  • Unnecessary GitHub Actions minutes
  • Unnecessary Claude API calls
  • Confusion from duplicate comment threads

🧪 Test Coverage

Not applicable - This PR modifies GitHub Actions workflows and documentation, which are not covered by pytest.

Recommendation: After merging, manually test the workflow:

  1. Create a test issue with format: scatter-test-999: Test Plot
  2. Add approved label
  3. Verify spec-to-code.yml posts @claude comment
  4. Verify claude.yml triggers exactly once
  5. Verify no duplicate invocations

📝 Minor Documentation Suggestions

  1. Line 38-41 (spec-to-code.yml): The warning message says "Please ensure the spec file is created before code generation", but the instructions in the @claude comment (line 65-66) say "If file doesn't exist, create it from the issue body". These are slightly contradictory. The actual behavior (continue with warning) is correct, but the warning message could be clearer:

    echo "⚠️  Warning: Spec file specs/${SPEC_ID}.md does not exist"
    echo "Claude Code will attempt to create it from the issue body"
  2. Line 94-95 (spec-to-code.yml): Comment says "Use deterministic sample data (fixed seeds or hardcoded data)" - This is excellent guidance and should also be in the generation rules files.

✅ Verdict

APPROVED - This is a well-thought-out change that solves a real problem with minimal risk. The documentation is excellent and the code changes are surgical.

Merge Confidence: High ✅

Suggested Next Steps (Optional)

  1. After merge, test the workflow manually as described above
  2. Consider adding the minor documentation clarification suggested in point Add workflow diagram for new prototype discovery #1
  3. Clarify whether quality-check.yml changes are planned or already implemented

Great work on improving the automation workflow! This is exactly the kind of proactive improvement that keeps the system maintainable. 🚀

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the Claude Code automation workflow to prevent duplicate triggers by removing direct issue opening events from claude.yml. The new architecture uses a two-stage approach where spec-to-code.yml posts an @claude comment, which then triggers claude.yml via comment events only.

  • Removed issues: types: [opened, assigned] trigger from claude.yml to avoid race conditions
  • Updated documentation to reflect the new two-workflow architecture for code generation and quality checks
  • Clarified the orchestration pattern where trigger workflows post @claude comments

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
.github/workflows/claude.yml Removed issue opening trigger and corresponding condition check, now only triggers on comment events
docs/architecture/automation-workflows.md Updated documentation to explain the two-workflow architecture (spec-to-code.yml + claude.yml, quality-check.yml + claude.yml) and their interaction via @claude comments

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

spec_id:
required: true
workflow_run:
workflows: ["Test and Preview"]
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow name reference is incorrect. The documentation references "Test and Preview" but the actual workflow in .github/workflows/test-and-preview.yml is named "Test and Generate Previews". This should be updated to match the actual workflow name to ensure the workflow_run trigger works correctly.

Suggested change
workflows: ["Test and Preview"]
workflows: ["Test and Generate Previews"]

Copilot uses AI. Check for mistakes.
MarkusNeusinger added a commit that referenced this pull request Dec 1, 2025
…erge-01D6cfGXen5SRMqh8Xgf7iUn

Create test issue and merge via GitHub
MarkusNeusinger pushed a commit that referenced this pull request Dec 29, 2025
Medium Priority Tasks (#6 & #7):

Integration Tests:
- Add aiosqlite dependency for async SQLite testing
- Create comprehensive test database fixtures with sample data
- Add integration tests for all repository CRUD operations
- Add E2E integration tests for all API endpoints
- Test full stack with real database and async operations

Error Handling Standardization:
- Create api/exceptions.py with standardized error types
- Add custom exceptions: PyplotsException, ResourceNotFoundError,
  DatabaseNotConfiguredError, ExternalServiceError, ValidationError
- Register global exception handlers in api/main.py
- Update all routers to use standardized exceptions
- Replace 14+ HTTPException raises with consistent error helpers
- Provide uniform error response format across API

Testing:
- 180+ test cases covering repositories and API endpoints
- Full coverage of CRUD operations with real database
- Async test fixtures for database setup and teardown

Benefits:
- Consistent error messages and HTTP status codes
- Better error tracking and debugging
- Comprehensive integration test coverage
- Improved API reliability and user experience
MarkusNeusinger pushed a commit that referenced this pull request Dec 29, 2025
Medium Priority Tasks (#6 & #7):

Integration Tests:
- Add aiosqlite dependency for async SQLite testing
- Create comprehensive test database fixtures with sample data
- Add integration tests for all repository CRUD operations
- Add E2E integration tests for all API endpoints
- Test full stack with real database and async operations

Error Handling Standardization:
- Create api/exceptions.py with standardized error types
- Add custom exceptions: PyplotsException, ResourceNotFoundError,
  DatabaseNotConfiguredError, ExternalServiceError, ValidationError
- Register global exception handlers in api/main.py
- Update all routers to use standardized exceptions
- Replace 14+ HTTPException raises with consistent error helpers
- Provide uniform error response format across API

Testing:
- 180+ test cases covering repositories and API endpoints
- Full coverage of CRUD operations with real database
- Async test fixtures for database setup and teardown

Benefits:
- Consistent error messages and HTTP status codes
- Better error tracking and debugging
- Comprehensive integration test coverage
- Improved API reliability and user experience
MarkusNeusinger added a commit that referenced this pull request Jan 26, 2026
Critical fixes:
- Fix TypeError: flatten tag dict to list for repository call (#6)
  Changed search_by_tags to receive list[str] instead of dict[str, list[str]]
  Repository expects flat list of tag values, not nested dict

- Add missing dataprep and styling parameters (#1, #7)
  Added to search_specs_by_tags function signature and docstring
  These categories were documented but not implemented

- Add filter logic for dataprep and styling (#2)
  Implemented filtering checks similar to other impl-level tags
  Ensures new parameters actually filter results

- Update condition to include dataprep and styling (#3)
  Modified impl-level filtering condition on line 117
  Now checks all 6 impl-level tag categories

Improvements:
- Add database error handling with helpful messages (#8)
  Check is_db_configured() before all database operations
  Provides clear error message if DATABASE_URL not set

- Update test mocks to match fixed interface (#5)
  Tests now verify flattened tag list instead of dict
  Added new test for dataprep/styling filter parameters
  Mock is_db_configured to return True in test fixture

Verification:
- All 16 unit tests passing
- Ruff linting and formatting applied
- No routing conflicts (#4 verified - no /mcp routes in routers)

Related: PR #4132, Issue #4129
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants