Skip to content

Align CI workflows with datamodel-code-generator#539

Merged
koxudaxi merged 4 commits intomainfrom
align-dcg-prompt-data
Apr 22, 2026
Merged

Align CI workflows with datamodel-code-generator#539
koxudaxi merged 4 commits intomainfrom
align-dcg-prompt-data

Conversation

@koxudaxi
Copy link
Copy Markdown
Owner

@koxudaxi koxudaxi commented Apr 22, 2026

Summary by CodeRabbit

  • Chores

    • Updated CI workflows: refined triggers for docs/LLM builds, simplified deploy checks, and changed some build/check modes
    • Removed Black from test extras
  • Refactor

    • Reduced generated prompt payload to a compact mapping of CLI option descriptions
    • Prompt-data build now uses a simplified generation pipeline and defaults output location
  • Documentation

    • Split and clarified separate --input / --output CLI reference sections
  • Tests

    • Updated tests to validate the new prompt-data output and CLI doc metadata

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

Walkthrough

Emit a compact OPTION_DESCRIPTIONS mapping from CLI docs; simplify build_prompt_data script and generated module; adjust CI workflow triggers and build invocations; update tests and docs to split --input/--output; remove Black from test extras. (47 words)

Changes

Cohort / File(s) Summary
Workflows: triggers & build invocations
​.github/workflows/cli-docs.yml, ​.github/workflows/llms-txt.yml, ​.github/workflows/test.yml, ​.github/workflows/config-types.yml
Changed pull_request.paths globs in some workflows; switched several CI steps from -- --check to build mode; removed explicit --output fastapi_code_generator/prompt_data.py args when invoking scripts/build_prompt_data.py.
Docs deploy & generated-doc sync
​.github/workflows/docs-deploy.yml, ​.github/workflows/generated-docs-sync.yml
Ensure docs/changelog.md exists (copy or generate fallback); removed pre-deploy credential validation step and stopped calling scripts/update_docs_version.py / GH token injection in generated-docs sync.
Prompt-data script & generated module
scripts/build_prompt_data.py, fastapi_code_generator/prompt_data.py
Reworked builder to produce OPTION_DESCRIPTIONS: dict[str,str] from .cli_doc JSON; removed prior rich PROMPT_DATA, dropped --output handling and previous function signature; writer now emits typed OPTION_DESCRIPTIONS.
Tests
tests/test_prompt_data.py, tests/main/test_main.py
Updated tests to assert OPTION_DESCRIPTIONS contents, truncation/ellipsis rules, new --check return codes and stderr lines; CLI-doc test metadata split into separate --input and --output decorators.
Docs content
docs/cli-reference.md, docs/llms-full.txt
Split combined --input, --output documentation into separate --output and --input sections and added cross-references and examples.
Project config
pyproject.toml
Removed black==24.10.0 from the test extras.
Small workflow sync file
​.github/workflows/generated-docs-sync.yml
Stopped injecting GH token and removed scripts/update_docs_version.py invocation.

Sequence Diagram(s)

sequenceDiagram
    participant GH as GitHub Actions
    participant Script as build_prompt_data.py
    participant Module as fastapi_code_generator/prompt_data.py
    participant DocsTests as Docs & Tests

    GH->>Script: run build_prompt_data (CI job)
    Script->>Script: parse tests/cli_doc/.cli_doc_collection.json
    Script->>Module: write OPTION_DESCRIPTIONS mapping
    Module-->>DocsTests: consumed by docs generation & tests
    DocsTests->>GH: report success/failure
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐇 I hopped through JSON fields and trimmed the sprawling trees,
Kept only tiny option notes that whisper on the breeze.
Workflows pruned their pathways, tests rearranged the tune,
A snug, concise map of flags beneath the quiet moon. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Align CI workflows with datamodel-code-generator' accurately summarizes the main objective of the pull request, which involves aligning multiple GitHub Actions workflows and supporting scripts with the practices from datamodel-code-generator.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch align-dcg-prompt-data

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 22, 2026

📚 Docs Preview: https://pr-539.fastapi-code-generator.pages.dev

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 22, 2026

Merging this PR will not alter performance

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

✅ 1 untouched benchmark


Comparing align-dcg-prompt-data (936cf88) with main (d50e829)

Open in CodSpeed

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (d50e829) to head (936cf88).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #539   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           16        16           
  Lines         1022      1012   -10     
  Branches       110       110           
=========================================
- Hits          1022      1012   -10     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
tests/test_prompt_data.py (1)

53-73: LGTM — fixture exercises dedupe, truncation, and empty-description skip.

Good coverage: the second --input item validates that the first-seen description wins, --long validates truncation/ellipsis, and --empty validates the empty-description skip.

One optional addition: assert the truncated --long line stays within the 120-column budget, which is the implicit contract of the truncation logic.

     assert "..." in content
+    long_lines = [ln for ln in content.splitlines() if ln.startswith('    "--long":')]
+    assert long_lines and all(len(ln) <= 120 for ln in long_lines)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_prompt_data.py` around lines 53 - 73, Add an assertion in
test_build_prompt_data_generates_file that locates the generated '--long' option
line in the file content (after calling build_prompt_data with OUTPUT_PATH set)
and verifies its string length does not exceed 120 characters; specifically,
find the line containing '"--long":' in the content variable and assert
len(line) <= 120 to enforce the truncation/ellipsis contract implemented by the
prompt_data logic.
scripts/build_prompt_data.py (1)

53-60: Truncation boundary can interact with escape sequences — current fallback is narrow.

After replace("\\", "\\\\") and replace('"', '\\"'), escaped_description can contain multi-char sequences (\\, \"). Slicing at max_description_length - 3 may land inside one of them. removesuffix("\\") only handles a single trailing \; if a truncated \\ leaves a lone \ it's fixed, but if it leaves \\ (both halves retained) followed by ... the result happens to be valid — this is working by luck of the boundary cases rather than by design.

Consider truncating the raw description first and escaping afterwards, which sidesteps the class of issues entirely:

♻️ Proposed refactor
-    for option, description in sorted(descriptions.items()):
-        escaped_description = description.replace("\\", "\\\\").replace('"', '\\"')
-        max_description_length = 120 - len(f'    "{option}": "",')
-        if len(escaped_description) > max_description_length:
-            truncated_description = escaped_description[: max_description_length - 3]
-            truncated_description = truncated_description.removesuffix("\\")
-            escaped_description = truncated_description + "..."
-        lines.append(f'    "{option}": "{escaped_description}",')
+    for option, description in sorted(descriptions.items()):
+        max_description_length = 120 - len(f'    "{option}": "",')
+        if len(description) > max_description_length:
+            description = description[: max_description_length - 3] + "..."
+        escaped_description = description.replace("\\", "\\\\").replace('"', '\\"')
+        lines.append(f'    "{option}": "{escaped_description}",')

Note: this changes the budget to apply to the pre-escape length, so a description full of quotes/backslashes could still exceed 120 columns on the generated line — acceptable for a cosmetic budget, and the output stays valid.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/build_prompt_data.py` around lines 53 - 60, The truncation should
operate on the raw description before escaping to avoid slicing inside escape
sequences: for each option in descriptions, compute max_raw_length = 120 -
len(f'    "{option}": "",') and if len(description) > max_raw_length, truncate
the raw description to max_raw_length - 3, append "..." to that raw truncated
text, then perform escaping (description.replace("\\", "\\\\").replace('"',
'\\"')) and use the escaped result when building the lines list (i.e., replace
the current escaped_description/truncated_description/removesuffix logic with
truncate-then-escape and append f'    "{option}": "{escaped_after_truncate}",').
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@fastapi_code_generator/prompt_data.py`:
- Around line 16-19: The "--output" option description was accidentally
copy-pasted from "--input"; update the value for the key "--output" in
prompt_data.py so it contains the correct description (e.g., "Path or directory
to write the generated FastAPI application files" or similar), ensuring it no
longer duplicates the "--input" text; also verify other option descriptions in
the same mapping to ensure they weren't similarly duplicated and, if this file
is generated, adjust the upstream marker generating the option_description
grouping so "--output" gets its own distinct description rather than inheriting
"--input"'s text.

---

Nitpick comments:
In `@scripts/build_prompt_data.py`:
- Around line 53-60: The truncation should operate on the raw description before
escaping to avoid slicing inside escape sequences: for each option in
descriptions, compute max_raw_length = 120 - len(f'    "{option}": "",') and if
len(description) > max_raw_length, truncate the raw description to
max_raw_length - 3, append "..." to that raw truncated text, then perform
escaping (description.replace("\\", "\\\\").replace('"', '\\"')) and use the
escaped result when building the lines list (i.e., replace the current
escaped_description/truncated_description/removesuffix logic with
truncate-then-escape and append f'    "{option}": "{escaped_after_truncate}",').

In `@tests/test_prompt_data.py`:
- Around line 53-73: Add an assertion in test_build_prompt_data_generates_file
that locates the generated '--long' option line in the file content (after
calling build_prompt_data with OUTPUT_PATH set) and verifies its string length
does not exceed 120 characters; specifically, find the line containing
'"--long":' in the content variable and assert len(line) <= 120 to enforce the
truncation/ellipsis contract implemented by the prompt_data logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bffb50de-62cf-46bd-865f-e6b93cef5d55

📥 Commits

Reviewing files that changed from the base of the PR and between d50e829 and 038deb4.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • .github/workflows/cli-docs.yml
  • .github/workflows/docs-deploy.yml
  • .github/workflows/generated-docs-sync.yml
  • .github/workflows/llms-txt.yml
  • fastapi_code_generator/prompt_data.py
  • pyproject.toml
  • scripts/build_prompt_data.py
  • tests/test_prompt_data.py
💤 Files with no reviewable changes (1)
  • pyproject.toml

Comment thread fastapi_code_generator/prompt_data.py Outdated
@koxudaxi koxudaxi changed the title Align prompt data flow Fix prompt data option descriptions Apr 22, 2026
@koxudaxi koxudaxi changed the title Fix prompt data option descriptions Align CI workflows with datamodel-code-generator Apr 22, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
tests/test_prompt_data.py (2)

114-116: Cumulative capsys buffer — intentional but brittle.

build_prompt_data(check=False) at line 114 prints a Generated: ... line to stdout; since capsys.readouterr() isn't called between L114 and L116, the assertion on splitlines()[-1] works only because the subsequent check=True call appends the OK: line last. This is correct today but couples the test to print ordering across two separate invocations. A quick capsys.readouterr() after L114 would make the intent of L116 (asserting the OK: line from the check run specifically) unambiguous.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_prompt_data.py` around lines 114 - 116, The test relies on a
cumulative capsys buffer across two calls to build_prompt_data, making the final
assertion brittle; after calling build_prompt_data(check=False) capture and
clear stdout by calling capsys.readouterr() before invoking
build_prompt_data(check=True) so the final assertion
capsys.readouterr().out.splitlines()[-1] == f"OK: {output_path}" only checks the
output produced by the check=True run; reference the build_prompt_data function
and capsys.readouterr() to locate where to insert the extra readouterr() call.

32-43: Optional: make "first-wins" semantics for duplicate options explicit.

The fixture implicitly exercises two behaviors of build_prompt_data:

  1. When the same option appears twice (--input at items 0 and 2), the first-seen option_description wins and the multiline variant is ignored.
  2. Only the first line of a multiline description is taken (would matter if the multiline entry were first).

Only (1) is asserted. Consider adding a small assertion that "Extra detail." is not in the generated content, so a future regression that inverts the iteration order or changes the dedup policy is caught explicitly.

✏️ Suggested additional assertion
     assert "--empty" not in content
+    assert "Extra detail." not in content
     assert "..." in content
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_prompt_data.py` around lines 32 - 43, The test currently asserts
that the first-seen description wins for duplicate options but doesn't assert
the multiline second occurrence was ignored; update the test for
build_prompt_data to also assert that the string "Extra detail." (the
description from the later duplicate marker for "--input") does NOT appear in
the generated prompt content, referencing the duplicate markers (the entries
with marker_kwargs.options ["--input"] and the multiline entry at index 2) so
the first-wins deduplication behavior and the "first-line only" rule are
explicitly checked.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/test_prompt_data.py`:
- Around line 114-116: The test relies on a cumulative capsys buffer across two
calls to build_prompt_data, making the final assertion brittle; after calling
build_prompt_data(check=False) capture and clear stdout by calling
capsys.readouterr() before invoking build_prompt_data(check=True) so the final
assertion capsys.readouterr().out.splitlines()[-1] == f"OK: {output_path}" only
checks the output produced by the check=True run; reference the
build_prompt_data function and capsys.readouterr() to locate where to insert the
extra readouterr() call.
- Around line 32-43: The test currently asserts that the first-seen description
wins for duplicate options but doesn't assert the multiline second occurrence
was ignored; update the test for build_prompt_data to also assert that the
string "Extra detail." (the description from the later duplicate marker for
"--input") does NOT appear in the generated prompt content, referencing the
duplicate markers (the entries with marker_kwargs.options ["--input"] and the
multiline entry at index 2) so the first-wins deduplication behavior and the
"first-line only" rule are explicitly checked.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8563cf77-a858-4b6a-931d-90d20af4b346

📥 Commits

Reviewing files that changed from the base of the PR and between 038deb4 and c331577.

📒 Files selected for processing (4)
  • docs/cli-reference.md
  • fastapi_code_generator/prompt_data.py
  • tests/main/test_main.py
  • tests/test_prompt_data.py
✅ Files skipped from review due to trivial changes (1)
  • docs/cli-reference.md

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/config-types.yml:
- Line 47: The CI currently runs the generator in write mode via the "tox -e
config-types" job which, per fastapi_code_generator/config.py (check=False
behavior), will overwrite committed types instead of failing; update the
workflow step to restore the check flag (i.e., run "tox -e config-types --
--check") so generator runs in validation mode, or if you must keep the write
build then add an explicit clean-worktree assertion immediately after the
generation step (run a git-diff/clean-check and fail the job if uncommitted
changes are present) to ensure stale generated types cause the job to fail.

In @.github/workflows/test.yml:
- Around line 56-57: The CI step "Build CLI docs" (and the similar generator
steps later) currently runs generators in write mode (e.g. "tox -e cli-docs")
which will silently update files and still exit 0; change these steps to
validation mode by adding the generators' check flag (e.g. pass --check or the
equivalent to the tox target invoked by "tox -e cli-docs") or, alternatively,
keep the build but add a "git diff --exit-code" immediately after each generator
step so the job fails if any files were modified; update the "Build CLI docs"
step and the corresponding generator steps referenced in the comment to use the
check flag or follow with git diff --exit-code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d658cd7c-ed3e-4c9d-8f4a-d02eaa5250c4

📥 Commits

Reviewing files that changed from the base of the PR and between 26597ff and 936cf88.

📒 Files selected for processing (2)
  • .github/workflows/config-types.yml
  • .github/workflows/test.yml

Comment thread .github/workflows/config-types.yml
Comment thread .github/workflows/test.yml
@koxudaxi koxudaxi merged commit a491d30 into main Apr 22, 2026
45 checks passed
@koxudaxi koxudaxi deleted the align-dcg-prompt-data branch April 22, 2026 22:58
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.

1 participant