Skip to content

feat: add Ruff workflow generation and uv support - #499

Open
Arifuzzamanjoy wants to merge 3 commits into
aimclub:mainfrom
Arifuzzamanjoy:feat/ruff-and-uv-workflows
Open

feat: add Ruff workflow generation and uv support#499
Arifuzzamanjoy wants to merge 3 commits into
aimclub:mainfrom
Arifuzzamanjoy:feat/ruff-and-uv-workflows

Conversation

@Arifuzzamanjoy

Copy link
Copy Markdown

Two related additions to workflow generation: a Ruff job and a use_uv flag.

Ruff (--include-ruff) generates a lint + format-check job across all three
backends — GitHub via astral-sh/ruff-action, GitLab and SourceCraft via a
plain pip install. Ruff has become the default choice for new Python projects,
so it seemed worth offering alongside flake8/pylint.

uv (--use-uv) swaps pip for uv in the generated dependency-install steps.
GitHub gets an astral-sh/setup-uv@v7 step; GitLab and SourceCraft bootstrap uv
inside the script since their runners are plain python: images. Uses
uv pip install --system throughout, since none of these run inside a venv.

Ruff's formatter and Black will fight if both are enabled, so
generate_selected_jobs logs a warning and the docs table notes it.

Pinned to floating major tags (@v7, @v3) to match the existing
actions/checkout@v4 convention rather than pinning exact patches.

Config, CLI args, and the scheduler docs table are all updated. Seven new tests
covering Ruff generation and the uv paths on each backend.

Two unrelated bugs turned up while testing this — the ${{ }} collapse in
generate_unit_test and the {branches_section} indentation in the GitLab
unit_test.yml template. Both predate this branch, so I've left them alone and
will file them separately.

@DRMPN

DRMPN commented Aug 24, 2026

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 39205d24f4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +665 to +666
install_cmd = "uv pip install --system" if use_uv else "pip install"
return self._cube("black", python_version, [f"{install_cmd} black", f"black {options} {src}"])

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Bootstrap uv before running SourceCraft jobs

When use_uv=True on SourceCraft, every affected cube runs uv pip install inside a plain docker.io/library/python:* image, but unlike the GitLab path no preceding command installs uv. Since those images do not provide the uv executable, generated lint and test jobs fail immediately with uv: command not found; prepend a bootstrap step to each cube before invoking uv.

Useful? React with 👍 / 👎.

"include_pep8": ["lint", "Lint", "pep8_check"],
"include_autopep8": ["autopep8"],
"include_fix_pep8": ["fix_pep8_command", "fix-pep8"],
"include_ruff": ["ruff", "ruff-lint", "ruff-format"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Filter existing Ruff jobs in the legacy workflow plan

When the legacy scheduler is used with include_ruff=True and repository inspection finds an existing ruff, ruff-lint, or ruff-format job, this mapping computes job_exists, but build_actual_plan() does not include include_ruff in any branch that applies and not job_exists; it falls through and keeps the flag enabled. Consequently GitHub generation can overwrite an existing ruff.yml or add a duplicate Ruff workflow instead of honoring the existing-job suppression used for the other job types.

Useful? React with 👍 / 👎.

Comment on lines +221 to +223
if use_uv:
uv_setup_step = ' - name: "Set up uv"\n uses: astral-sh/setup-uv@v7\n'
install_command = "uv pip install --system -r requirements.txt && uv pip install --system pytest pytest-cov"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve custom dependency commands when uv is enabled

When a caller supplies a custom dependencies_command to generate_unit_test() and also enables use_uv, this branch silently discards that command and assumes the repository has requirements.txt. For example, a project passing uv pip install --system -e . because it has only pyproject.toml receives a workflow that fails on the nonexistent requirements file; the uv path should retain an explicitly supplied installation command or provide a separate uv-specific override.

Useful? React with 👍 / 👎.

include_fix_pep8: bool = Field(default=False, description="Include fix-pep8 command workflow.")
include_pypi: bool = Field(default=False, description="Include PyPI publish workflow.")
include_ruff: bool = Field(default=False, description="Include Ruff linter and formatter workflow.")
use_uv: bool = Field(default=False, description="Use uv instead of pip for dependency installation in workflows.")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Apply use_uv to PyPI publishing workflows

When include_pypi=True, use_poetry=False, and use_uv=True, all three backends still generate their existing bare pip install step for build and publishing dependencies because none of the generate_pypi_publish() calls receive or honor this setting. This contradicts the new flag's workflow-wide dependency-install behavior and prevents users from obtaining an all-uv workflow; propagate the setting into the publishing generators and emit the corresponding setup/bootstrap step.

Useful? React with 👍 / 👎.

Comment on lines +759 to +760
if settings.include_ruff:
lint_cubes.append(self.generate_ruff(python_version=latest, use_uv=settings.use_uv))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Merge Ruff into existing SourceCraft lint workflows

When a SourceCraft repository already has a workflows.lint definition but no Ruff cube, this newly created cube is placed in a replacement workflows_section["lint"]; the later merge deliberately retains the existing key without merging its cubes, so the Ruff request is silently discarded while include_ruff is marked done and generation reports success. Merge the Ruff cube into the existing lint workflow, or otherwise report that it was not added.

Useful? React with 👍 / 👎.

@DRMPN DRMPN left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hi Arifuzzaman Joy,

Thank you for your contribution to the project!

Could you please address the changes described in the comments.

Additionally, could you add tests to verify the indentation of the generated YAML configs after the placeholders are populated?

Finally, please consider the Codex review comments as well.

Comment thread docs/scheduler/index.md Outdated
Comment on lines +165 to +166
!!! warning "Ruff + Black conflict"
Enabling both `--include-ruff` and `--include-black` generates CI jobs that may produce conflicting formatting results, since Ruff's formatter and Black apply different style rules. Prefer one formatter per project.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could we format this line as "Note: ..." not as "!!! warning".

stage: fix
script:
- pip install autopep8
{uv_bootstrap} - {install_command} autopep8

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  1. The inline {uv_bootstrap} is a syntax breaker.

python-version: {python_version}
- name: "Install dependencies"
run: "pip install {tool}"
{uv_setup_step} - name: "Install dependencies"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  1. The {uv_setup_step} placement is fragile.

Comment on lines +20 to +24
{uv_setup_step} - name: "Install dependencies"
run: "{install_command}"
- name: "Run tests"
run: "{test_command} --cov=."
{codecov_step} No newline at end of file
run: "{test_command} --cov=."
{codecov_step}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  1. The {uv_setup_step} placement is fragile.
Suggested change
{uv_setup_step} - name: "Install dependencies"
run: "{install_command}"
- name: "Run tests"
run: "{test_command} --cov=."
{codecov_step}
\ No newline at end of file
run: "{test_command} --cov=."
{codecov_step}
{uv_setup_step}
- name: "Install dependencies"
run: "{install_command}"
- name: "Run tests"
run: "{test_command} --cov=."
{codecov_step}

Comment on lines 5 to 6
{uv_bootstrap} - {install_command} black
- black {src} {black_options}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  1. The inline {uv_bootstrap} is a syntax breaker, please change others accordingly.
Suggested change
{uv_bootstrap} - {install_command} black
- black {src} {black_options}
{uv_bootstrap}
- {install_command} black
- black {src} {black_options}

stage: lint
script:
- pip install {tool}
{uv_bootstrap} - {install_command} {tool}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  1. The inline {uv_bootstrap} is a syntax breaker.

image: python:${{PYTHON_VERSION}}
before_script:
- pip install -r requirements.txt pytest
{uv_bootstrap} - {install_command} -r requirements.txt pytest

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  1. The inline {uv_bootstrap} is a syntax breaker

str: Path to the generated file.
"""
if use_uv:
uv_setup_step = ' - name: "Set up uv"\n uses: astral-sh/setup-uv@v7\n'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  1. Remove indentation.

tool_command = f"{tool} {args}" if args else tool

if use_uv:
uv_setup_step = ' - name: "Set up uv"\n uses: astral-sh/setup-uv@v7\n'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  1. Remove indentation.

that installs uv itself (empty when use_uv is False).
"""
if use_uv:
return "uv pip install --system", " - pip install uv\n"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  1. Remove indentation.

@Arifuzzamanjoy

Copy link
Copy Markdown
Author

Thanks for the review!

I just pushed an update to address all the comments:

  • Put {uv_bootstrap} and {uv_setup_step} on their own separate lines.
  • Removed extra spaces from the Python strings.
  • Made sure SourceCraft installs uv before trying to use it (Codex P1).
  • Fixed it so it won't add a Ruff job if one already exists (Codex P2).
  • Allowed custom install commands when use_uv is on, instead of always expecting a requirements.txt file (Codex P2).
  • Changed !!! warning to Note: in the documentation.
  • Added 5 new tests verifying YAML indentation after placeholder substitution

@Arifuzzamanjoy
Arifuzzamanjoy requested a review from DRMPN August 29, 2026 11:16
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.

2 participants