github output#1049
Conversation
✅ Deploy Preview for djlint canceled.
|
|
Hi. Am I understanding correctly that this is for automatic code reviews in GitHub Actions when using djLint? |
|
Yes. This formats the output in a way that displays the errors in the GitHub annotations view. It detects when the user is on GitHub Actions and switches to this format automatically |
|
Hi! Sorry it took too long to review. Please resolve conflicts, run |
defa690 to
8131b82
Compare
|
Rebased + formatted! |
There was a problem hiding this comment.
Pull Request Overview
This PR adds GitHub Actions integration by implementing GitHub-compatible output formatting for djLint. When running in GitHub Actions environments, the tool will output lint and format errors in a format that can be displayed as annotations in the GitHub interface.
Key changes:
- Adds a new
--github-outputflag that defaults toTruewhen running in GitHub Actions - Implements GitHub workflow command output format for both lint and format errors
- Disables progress bars when GitHub output is enabled
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/djlint/settings.py | Adds github_output parameter to the Config class constructor |
| src/djlint/github_output.py | New module implementing GitHub workflow command output formatting |
| src/djlint/init.py | Integrates GitHub output option, disables progress bars when enabled, and calls GitHub output function |
| no_function_formatting: bool, | ||
| no_set_formatting: bool, | ||
| max_blank_lines: int | None, | ||
| github_output: bool = False, |
There was a problem hiding this comment.
The default value False in the function signature conflicts with the click option default of bool(os.getenv("GITHUB_ACTIONS")). This creates inconsistent behavior where the parameter default doesn't match the CLI default. Remove the default value from the parameter since it's already handled by the click option.
| github_output: bool = False, | |
| github_output: bool, |
| no_set_formatting: bool = False, | ||
| max_blank_lines: int | None = None, | ||
| github_output: bool = False, | ||
| ) -> None: |
There was a problem hiding this comment.
The github_output parameter is added to the Config constructor but is never assigned to a class attribute. This means the parameter is accepted but not stored, making it unusable. Add self.github_output = github_output in the constructor body.
| ) -> None: | |
| ) -> None: | |
| self.github_output = github_output |
| ) -> None: | ||
| """djLint · HTML template linter and formatter.""" | ||
|
|
||
| config = Config( |
There was a problem hiding this comment.
The github_output parameter is not passed to the Config constructor, but it's been added as a parameter. This will cause the Config object to use the default value instead of the CLI option value. Add github_output=github_output, to the Config constructor call.
8131b82 to
1d29606
Compare
1d29606 to
24f8dc5
Compare
|
@monosans sorry this took so long, mind taking another look? i think I've fixed all of the issues. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| if ( | ||
| config.github_output | ||
| and print_github_output(config, file_errors, len(file_list)) | ||
| and not config.warn | ||
| ): | ||
| sys.exit(1) | ||
|
|
||
| if print_output(config, file_errors, len(file_list)) and not config.warn: |
There was a problem hiding this comment.
When config.github_output is enabled, the code still calls print_output(...) afterwards. That means GitHub log commands can be mixed with the normal console output on successful runs (and on --warn runs), which can make CI logs noisy and can confuse parsers that expect only workflow commands. Consider skipping print_output entirely when github_output is enabled (or gating it behind not config.github_output).
| for message_dict in errors: | ||
| line = message_dict["line"].split(":")[0] | ||
| level = "error" if message_dict["code"].startswith("E") else "warning" | ||
| echo( | ||
| f"::{level} file={filename},line={line}::{message_dict['code']} {message_dict['message']}" | ||
| ) |
There was a problem hiding this comment.
GitHub workflow/log commands require escaping in both the properties and message sections (e.g. %, \r, \n, and also : / , in properties). As written, a lint message containing newlines or % (or a filename containing ,) can produce malformed commands and missing annotations. Consider adding a small escape helper and applying it to filename, line, and the rendered message.
| def build_relative_path(url: str, project_root: Path) -> str: | ||
| """Get path relative to project.""" | ||
| url_path = Path(url) | ||
| if project_root != url_path and project_root in url_path.parents: | ||
| return str(url_path.relative_to(project_root)) | ||
| return url |
There was a problem hiding this comment.
build_relative_path duplicates the implementation already present in djlint.output.build_relative_path. Duplicating this utility increases the risk of the GitHub output path logic drifting from the normal console output over time. Consider importing and reusing the existing helper (or moving it to a shared module like helpers.py).
| ) | ||
| @click.option( | ||
| "--github-output", | ||
| is_flag=True, | ||
| default=bool(os.getenv("GITHUB_ACTIONS")), | ||
| help="Output GitHub-compatible formatting.", | ||
| show_default=True, |
There was a problem hiding this comment.
New CLI flag/output mode (--github-output) changes user-visible behavior and exit-code handling, but there are no tests covering it. There are existing Click CLI tests in tests/test_djlint/test_djlint.py; consider adding tests that (1) verify the flag can be enabled/disabled, (2) assert the presence of ::error/::warning lines for known lint/format failures, and (3) ensure normal console output is suppressed/unchanged as intended in this mode.
| "--github-output", | ||
| is_flag=True, |
There was a problem hiding this comment.
--github-output is declared as an is_flag=True option but has a default derived from GITHUB_ACTIONS. When GITHUB_ACTIONS is set (typical in CI), the default becomes True and there is no CLI way to turn the option off (Click flags can’t be negated unless you define a paired flag). Consider defining this as a boolean option pair (e.g. --github-output/--no-github-output) or using a None default and resolving the environment default inside main so users can still explicitly disable it.
| "--github-output", | |
| is_flag=True, | |
| "--github-output/--no-github-output", |
There was a problem hiding this comment.
I've addressed the review comments:
- CLI Flag & Default Value: Changed
--github-outputto a boolean flag pair (--github-output/--no-github-output) withdefault=None. The environment variableGITHUB_ACTIONSis now checked insidemainonly if the flag is not explicitly provided. This allows users to disable GitHub output even in CI environments. - Output Gating: Logic updated to ensure that
print_output(console output) is not called whengithub_outputis enabled, preventing mixed log output. - Escaping: Added
escape_dataandescape_propertyhelpers tosrc/djlint/github_output.pyto properly escape special characters (%,\r,\n,:,,) in GitHub workflow commands. - Code Duplication: Removed the duplicate
build_relative_pathinsrc/djlint/github_output.pyand imported it fromdjlint.output. - Testing: Added
tests/test_github_output.pycovering:- Explicit flag usage (
--github-output). - Environment variable fallback (
GITHUB_ACTIONS). - Explicit disabling (
--no-github-output). - Output format and escaping.
- Explicit flag usage (
All tests passed locally.
automatically enabled when GITHUB_ACTIONS exists
The github_output parameter was being accepted by both the main() function and Config.__init__(), but was not being: 1. Passed to the Config constructor when creating the config object 2. Stored as an instance variable in the Config class 3. Used consistently throughout the codebase (local variable vs config.github_output) This commit fixes all three issues by: - Adding self.github_output assignment in Config.__init__ - Passing github_output parameter when instantiating Config - Using config.github_output consistently instead of local variable All 573 tests pass after these changes.
- Fix unused parameter warning by prefixing file_count with underscore - Add type ignore comment for call-overload issue (matches pattern in output.py) - Fix import ordering to be alphabetical - Apply ruff formatting fixes (blank lines, line breaks) All pre-commit hooks pass: - ruff check: ✓ - ruff format: ✓ - mypy: ✓ - All 573 tests: ✓
- Change --github-output flag to boolean option pair (--github-output/--no-github-output) with None default - Resolve default github_output value in main based on GITHUB_ACTIONS env var - Gate console output to prevent mixing with GitHub workflow commands - Add proper escaping for GitHub workflow command values - Remove duplicate build_relative_path function - Add comprehensive tests for github output behavior
a0aaf29 to
4868ec3
Compare
|
@monosans ok, I think this is finally ready! |
|
@monosans anything I can do to get this merged in? |
Happy to add some test, point me to the right pattern and I'll add it in.
Pull Request Check List