Skip to content

github output#1049

Open
iloveitaly wants to merge 7 commits intodjlint:masterfrom
iloveitaly:github-output
Open

github output#1049
iloveitaly wants to merge 7 commits intodjlint:masterfrom
iloveitaly:github-output

Conversation

@iloveitaly
Copy link
Copy Markdown

Happy to add some test, point me to the right pattern and I'll add it in.

Pull Request Check List

  • Added tests for changed code.
  • Updated documentation for changed code.

@netlify
Copy link
Copy Markdown

netlify Bot commented Nov 28, 2024

Deploy Preview for djlint canceled.

Name Link
🔨 Latest commit 8131b82
🔍 Latest deploy log https://app.netlify.com/sites/djlint/deploys/67c1a15c3ca4f90008dd6968

@monosans
Copy link
Copy Markdown
Member

Hi. Am I understanding correctly that this is for automatic code reviews in GitHub Actions when using djLint?

@iloveitaly
Copy link
Copy Markdown
Author

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

@monosans
Copy link
Copy Markdown
Member

Hi! Sorry it took too long to review. Please resolve conflicts, run pre-commit run --all-files ruff-format and I will merge.

@iloveitaly
Copy link
Copy Markdown
Author

Rebased + formatted!

@monosans monosans requested a review from Copilot July 29, 2025 13:31
Copy link
Copy Markdown

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 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-output flag that defaults to True when 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

Comment thread src/djlint/__init__.py Outdated
no_function_formatting: bool,
no_set_formatting: bool,
max_blank_lines: int | None,
github_output: bool = False,
Copy link

Copilot AI Jul 29, 2025

Choose a reason for hiding this comment

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

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.

Suggested change
github_output: bool = False,
github_output: bool,

Copilot uses AI. Check for mistakes.
Comment thread src/djlint/settings.py
no_set_formatting: bool = False,
max_blank_lines: int | None = None,
github_output: bool = False,
) -> None:
Copy link

Copilot AI Jul 29, 2025

Choose a reason for hiding this comment

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

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.

Suggested change
) -> None:
) -> None:
self.github_output = github_output

Copilot uses AI. Check for mistakes.
Comment thread src/djlint/__init__.py
) -> None:
"""djLint · HTML template linter and formatter."""

config = Config(
Copy link

Copilot AI Jul 29, 2025

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
@iloveitaly
Copy link
Copy Markdown
Author

@monosans sorry this took so long, mind taking another look? i think I've fixed all of the issues.

Copy link
Copy Markdown

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

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.

Comment thread src/djlint/__init__.py Outdated
Comment on lines 463 to 471

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:
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

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).

Copilot uses AI. Check for mistakes.
Comment on lines +51 to +56
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']}"
)
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment thread src/djlint/github_output.py Outdated
Comment on lines +75 to +80
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
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

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).

Copilot uses AI. Check for mistakes.
Comment thread src/djlint/__init__.py Outdated
Comment on lines +248 to +254
)
@click.option(
"--github-output",
is_flag=True,
default=bool(os.getenv("GITHUB_ACTIONS")),
help="Output GitHub-compatible formatting.",
show_default=True,
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment thread src/djlint/__init__.py Outdated
Comment on lines +250 to +251
"--github-output",
is_flag=True,
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

--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.

Suggested change
"--github-output",
is_flag=True,
"--github-output/--no-github-output",

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I've addressed the review comments:

  1. CLI Flag & Default Value: Changed --github-output to a boolean flag pair (--github-output/--no-github-output) with default=None. The environment variable GITHUB_ACTIONS is now checked inside main only if the flag is not explicitly provided. This allows users to disable GitHub output even in CI environments.
  2. Output Gating: Logic updated to ensure that print_output (console output) is not called when github_output is enabled, preventing mixed log output.
  3. Escaping: Added escape_data and escape_property helpers to src/djlint/github_output.py to properly escape special characters (%, \r, \n, :, ,) in GitHub workflow commands.
  4. Code Duplication: Removed the duplicate build_relative_path in src/djlint/github_output.py and imported it from djlint.output.
  5. Testing: Added tests/test_github_output.py covering:
    • Explicit flag usage (--github-output).
    • Environment variable fallback (GITHUB_ACTIONS).
    • Explicit disabling (--no-github-output).
    • Output format and escaping.

All tests passed locally.

iloveitaly and others added 7 commits February 19, 2026 14:45
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
@iloveitaly
Copy link
Copy Markdown
Author

@monosans ok, I think this is finally ready!

@iloveitaly
Copy link
Copy Markdown
Author

@monosans anything I can do to get this merged in?

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.

4 participants