Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Sep 15, 2025

This PR implements a new GitHub Action that automatically formats Python code in MyST markdown files and standard markdown code blocks using black, addressing the need for consistent code formatting in QuantEcon documentation projects.

Key Features

Smart Markdown Parsing: The action uses a robust line-by-line parser that correctly handles both MyST {code-cell} directives and standard markdown fenced code blocks without interference between the two formats.

Language Detection: Automatically identifies Python code by language identifiers (python, python3, ipython, ipython3) and skips non-Python code blocks (e.g., Julia, JavaScript) with informative logging.

Black Integration: Formats Python code using black with configurable arguments, ensuring PEP8 compliance and consistent styling across all code blocks.

Glob Pattern Support: Accepts both explicit file paths and shell glob patterns for flexible file selection. Supports patterns like lecture/**/*.md to process all markdown files in a directory tree recursively.

PR Comment Trigger: Activates when PR comments contain @quantecon-code-style, automatically finding changed markdown files and applying formatting with individual commit messages per file.

Complete Workflow Setup: Provides production-ready workflow templates and comprehensive documentation to ensure proper integration in target repositories.

Usage Example

# Trigger via PR comment
# Just comment "@quantecon-code-style" on any PR

# Or use directly in workflows with explicit files
- name: Format Python code in markdown files
  uses: QuantEcon/meta/.github/actions/code-style-checker@main
  with:
    files: 'lecture/aiyagari.md,lecture/mccall.md'
    check-myst-code-cells: 'true'
    check-markdown-blocks: 'true'
    python-languages: 'python,python3,ipython,ipython3'
    black-args: '--line-length=88'

# Or use with glob patterns to process all files
- name: Format all lecture files
  uses: QuantEcon/meta/.github/actions/code-style-checker@main
  with:
    files: 'lecture/**/*.md'
    check-myst-code-cells: 'true'
    check-markdown-blocks: 'true'

Setup Instructions

To enable PR comment triggers, copy the complete workflow template from .github/workflows/code-style-formatter-template.yml to your repository as .github/workflows/code-style-formatter.yml. The template includes all necessary steps for proper PR integration:

  • PR information gathering for accurate file change detection
  • Comprehensive error handling and result reporting
  • Automated comment generation with formatting summaries
  • Conditional logic for cases where no formatting is needed

File Input Formats

The action supports multiple input formats for maximum flexibility:

  • Explicit file paths: 'file1.md,file2.md'
  • Glob patterns: 'lecture/**/*.md' (recursive), 'lecture/*.md' (single level)
  • Mixed input: 'lecture/**/*.md,specific-file.md'

Implementation Details

The action processes files in two phases:

  1. File Discovery: Expands glob patterns to actual file paths while maintaining backward compatibility with explicit file lists
  2. Standard Markdown Blocks: Uses line-by-line parsing to avoid regex conflicts with MyST blocks
  3. MyST Code-Cells: Uses regex pattern matching after standard blocks are processed

For each Python code block found, the action:

  • Creates a temporary Python file with the extracted code
  • Runs black with specified arguments
  • Replaces the original code with the formatted version
  • Commits each modified file individually with descriptive messages

Testing

Comprehensive test suite includes:

  • unformatted-code.md: Mixed MyST and markdown blocks with poor formatting
  • formatted-code.md: Well-formatted code to ensure no unnecessary changes
  • no-python-code.md: Non-Python languages to verify selective processing
  • Glob pattern tests: Verify recursive directory scanning and mixed input handling

Manual testing confirms the action correctly formats 5 code blocks (2 standard markdown + 3 MyST) while properly skipping non-Python content. Additional tests validate glob pattern expansion and file filtering functionality.

Documentation

  • Complete README: Updated with full workflow examples and setup instructions
  • Comprehensive Examples: Detailed usage scenarios for different repository configurations
  • Template Workflow: Ready-to-use workflow file that users can copy directly to their repositories

Fixes #221.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@Copilot Copilot AI changed the title [WIP] [code] code style checks (black) Add Code Style Formatter Action for Python code in MyST markdown files Sep 15, 2025
@Copilot Copilot AI requested a review from mmcky September 15, 2025 22:56
@mmcky
Copy link
Contributor

mmcky commented Sep 15, 2025

@copilot for the use case when using directly in workflows can

files: 'lecture/aiyagari.md,lecture/mccall.md'

accept patterns such as lecture/**/*.md for example to do a check of ALL files?

Copy link
Contributor Author

Copilot AI commented Sep 15, 2025

@copilot for the use case when using directly in workflows can

...

Yes! The action now supports glob patterns like lecture/**/*.md to check ALL files in a directory tree. You can use:

# All markdown files in lecture directory and subdirectories
files: 'lecture/**/*.md'

# Multiple directories
files: 'lecture/**/*.md,examples/**/*.md'

# Mix patterns with explicit files
files: 'lecture/**/*.md,specific-file.md'

The implementation maintains full backward compatibility with comma-separated explicit file paths and includes smart filtering to only process .md files even when glob patterns match other file types.

Commit: e1c0394

@Copilot Copilot AI changed the title Add Code Style Formatter Action for Python code in MyST markdown files Add Code Style Formatter Action for Python code in MyST markdown files with glob pattern support Sep 15, 2025
Copilot finished work on behalf of mmcky September 15, 2025 23:08

This comment was marked as off-topic.

This comment was marked as off-topic.

@mmcky
Copy link
Contributor

mmcky commented Sep 16, 2025

@copilot I just tested this in QuantEcon/lecture-python.myst#615 and it doesn't appear to run after making a comment QuantEcon/lecture-python.myst#615 (comment) that should activate the style checker workflow. Can you please take a look and let me know what I've done wrong or is this a bug?

Copy link
Contributor Author

Copilot AI commented Sep 16, 2025

@copilot I just tested this in QuantEcon/lecture-python.myst#615 and it doesn't appear to run after making a comment QuantEcon/lecture-python.myst#615 (comment)...

The issue is that the workflow file you added in the test PR is incomplete and has some problems:

  1. Missing branch reference: The workflow references @copilot/fix-221-3 which is a development branch. For production, it should reference @main.

  2. Missing PR information steps: The workflow needs to get PR information to determine which files changed.

  3. Incomplete workflow: Several important steps are missing compared to the full workflow.

The correct workflow should be:

name: Code Style Formatter
on:
  issue_comment:
    types: [created]

jobs:
  format-code:
    if: github.event.issue.pull_request && contains(github.event.comment.body, '@quantecon-code-style')
    runs-on: ubuntu-latest
    
    steps:
    - name: Get PR information
      id: pr
      uses: actions/github-script@v7
      with:
        script: |
          const { data: pullRequest } = await github.rest.pulls.get({
            owner: context.repo.owner,
            repo: context.repo.repo,
            pull_number: context.issue.number,
          });
          
          core.setOutput('head-sha', pullRequest.head.sha);
          core.setOutput('head-ref', pullRequest.head.ref);
          core.setOutput('base-sha', pullRequest.base.sha);
    
    - name: Checkout PR branch
      uses: actions/checkout@v4
      with:
        token: ${{ secrets.GITHUB_TOKEN }}
        ref: ${{ steps.pr.outputs.head-ref }}
        fetch-depth: 0
    
    - name: Get changed files
      id: changed-files
      uses: tj-actions/changed-files@v40
      with:
        files: '**/*.md'
        base_sha: ${{ steps.pr.outputs.base-sha }}
        sha: ${{ steps.pr.outputs.head-sha }}
    
    - name: Format MyST markdown files
      if: steps.changed-files.outputs.any_changed == 'true'
      uses: QuantEcon/meta/.github/actions/code-style-checker@main
      with:
        files: ${{ steps.changed-files.outputs.all_changed_files }}
        check-myst-code-cells: 'true'
        check-markdown-blocks: 'true'
        python-languages: 'python,python3,ipython,ipython3'
        black-args: '--line-length=88'
        commit-files: 'true'
        git-user-name: 'GitHub Action'
        git-user-email: '[email protected]'
    
    - name: Push changes
      if: steps.changed-files.outputs.any_changed == 'true'
      run: git push

Update your workflow file with this complete version and try commenting again.

@Copilot Copilot AI changed the title Add Code Style Formatter Action for Python code in MyST markdown files with glob pattern support Add Code Style Formatter Action for Python code in MyST markdown files with complete workflow setup Sep 16, 2025
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.

[code] code style checks (black)
2 participants