chore: sync template from tschm/.config-templates@main#25
Conversation
WalkthroughInstalls Task, uv, and uvx into a local ./bin via a new bash-based setup action and updates workflows, Taskfiles, and Makefile to invoke those local binaries; adds a pyproject existence output, expands workflow triggers/permissions, updates .gitignore and pre-commit ruff rev, and adds Makefile dry-run tests. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor CI as CI Runner
participant Setup as setup-project Action (bash installer)
participant Net as Internet/curl
participant Bin as repo ./bin (task, uv, uvx)
participant Workflow as GitHub Workflow jobs
participant Taskfile as Taskfiles / Makefile
participant Python as Python venv (uv)
CI->>Setup: invoke setup-project
Setup->>Net: curl download task/uv/uvx
Net-->>Bin: place binaries in ./bin
Setup->>Bin: verify versions, set outputs (pyproject_exists)
Setup->>Python: optionally ./bin/uv venv && ./bin/uv sync
Workflow->>Taskfile: start job (docs/tests/book/deptry)
Taskfile->>Bin: call ./bin/task / ./bin/uv / ./bin/uvx
Bin->>Python: manage venv, run tests/builds/docs
Python-->>Workflow: job results (success/fail)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
Makefile (1)
21-35: Fix PATH export to point at./bin.
export PATH=".bin:$$PATH"both points at the wrong directory (missing/) and, executed as a standalone recipe line, does not persist for later lines. If you still need this, fold it into the subsequent shell block and export./bin.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
.github/actions/setup-project/action.yml(2 hunks).github/workflows/book.yml(1 hunks).github/workflows/ci.yml(1 hunks).github/workflows/deptry.yml(1 hunks).github/workflows/marimo.yml(2 hunks).github/workflows/pre-commit.yml(1 hunks).github/workflows/sync.yml(2 hunks).gitignore(1 hunks).pre-commit-config.yaml(1 hunks)Makefile(1 hunks)Taskfile.yml(1 hunks)taskfiles/build.yml(3 hunks)taskfiles/docs.yml(7 hunks)taskfiles/quality.yml(1 hunks)
taskfiles/quality.yml
Outdated
| - ./bin/task build:uv | ||
| - ./bin/uvx ruff format . | ||
|
|
||
| lint: | ||
| desc: Run pre-commit hooks | ||
| deps: ['build:uv'] | ||
| cmds: | ||
| - uvx pre-commit run --all-files | ||
| - ./bin/task build:uv | ||
| - ./bin/uvx pre-commit run --all-files | ||
|
|
||
| deptry: | ||
| desc: Check for dependency issues | ||
| deps: ['build:uv'] | ||
| cmds: | ||
| - ./bin/task build:uv | ||
| - | | ||
| if [ -f "pyproject.toml" ]; then | ||
| SOURCE_FOLDER="$(fd -td . src -d1 --exclude '.*' | head -1)" : "${SOURCE_FOLDER:=src}" | ||
| # SOURCE_FOLDER="src/$(find src -mindepth 1 -maxdepth 1 -type d -not -path '*/\.*' | head -1 | sed 's|^src/||')" | ||
| uvx deptry $SOURCE_FOLDER {{.OPTIONS}} | ||
| SOURCE_FOLDER="src/$(find src -mindepth 1 -maxdepth 1 -type d -not -path '*/\.*' | head -1 | sed 's|^src/||')" | ||
| ./bin/uvx deptry $SOURCE_FOLDER {{.OPTIONS}} | ||
| else |
There was a problem hiding this comment.
Avoid re‑nesting Task when the local binary may be absent.
These tasks now shell out to ./bin/task build:uv, but in a fresh clone (or any environment before install-task runs) there is no ./bin/task yet. Running task quality:fmt or invoking the workflow will therefore fail before bootstrap completes. Please keep the bootstrap within Task itself (e.g., call task build:uv so the already-running Task instance handles the dependency) or ensure the composite bootstrap installs the local binary before these commands execute.
🤖 Prompt for AI Agents
In taskfiles/quality.yml around lines 12 to 29 the tasks shell out to ./bin/task
build:uv which will fail in a fresh clone before install-task creates that
binary; update these task cmds to invoke the already-running task binary (use
task build:uv instead of ./bin/task build:uv) so Task handles bootstrapping, or
alternatively add a preparatory step at the top of the task that ensures
./bin/task is installed before any other cmds run (e.g., run the install step
once at the start of the task).
| SOURCE_FOLDER="src/$(find src -mindepth 1 -maxdepth 1 -type d -not -path '*/\.*' | head -1 | sed 's|^src/||')" | ||
| ./bin/uvx deptry $SOURCE_FOLDER {{.OPTIONS}} |
There was a problem hiding this comment.
Single-package assumption breaks deptry coverage.
find src … | head -1 only inspects the first top-level package inside src/. Projects with multiple packages (e.g., src/api, src/cli) will quietly skip the others, reducing deptry’s usefulness. Either call deptry on the whole src tree or iterate over every child directory.
🤖 Prompt for AI Agents
In taskfiles/quality.yml around lines 27-28, the current command picks only the
first top-level package under src which skips other packages; change it to run
deptry across the full src tree by either setting SOURCE_FOLDER to "src" (so
deptry inspects all packages) or iterate over each top-level child directory
under src and invoke ./bin/uvx deptry for each—implement one of these two
options so deptry covers every package instead of just the first.
18cd2b7 to
4aebccf
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
taskfiles/docs.yml (1)
28-39: Missing explicit error handling in test task.The test task contains multiple shell commands without explicit error checking. If uv pip install or pytest fails, subsequent commands may still execute.
Apply this diff to add error handling:
- ./bin/task build:install - printf "${BLUE}[INFO] Running tests...${RESET}\n" - | + set -e # Find source folder SOURCE_FOLDER="src/$(find src -mindepth 1 -maxdepth 1 -type d -not -path '*/\.*' | head -1 | sed 's|^src/||')"Taskfile.yml (1)
63-73: Verify ./bin/task is available before invoking it in default and help tasks.Both the
defaultandhelptasks invoke./bin/taskdirectly without checking if the binary exists. These tasks are often run first by developers, before any setup steps.Consider adding error handling or making these tasks depend on build:uv:
default: desc: Display help information - silent: true - cmds: + silent: false + deps: [build:uv] + cmds: - ./bin/task --list help: desc: Display help information with all tasks - silent: true + silent: false + deps: [build:uv] cmds: - ./bin/task --list-allAlternatively, fall back to
taskif ./bin/task is not available:cmds: - - ./bin/task --list + - if [ -x "./bin/task" ]; then ./bin/task --list; else task --list; fi
♻️ Duplicate comments (2)
taskfiles/quality.yml (2)
25-26: Previous concern remains: local binary may be absent before bootstrap.The past review comment flagging the re-nesting issue is still applicable. These commands invoke
./bin/taskand./bin/uvx, which won't exist in a fresh clone untilinstall-taskcompletes. Running this task directly (e.g.,task quality:lint) before bootstrap will fail.
34-35: Previous concern remains: single-package assumption in deptry.The past review comment about
head -1limiting deptry to the first package undersrc/is still applicable. Projects with multiple top-level packages (e.g.,src/api,src/cli) will have incomplete coverage.
🧹 Nitpick comments (2)
.github/actions/setup-project/action.yml (1)
59-59: Pin copier version for reproducibility.Line 59 installs copier without a version pin:
pip install copier. This can lead to unpredictable behavior if copier releases breaking changes.Specify a version constraint for copier:
- name: Render the project if: hashFiles('tests/resources/render.yml') != '' shell: bash run: | - pip install copier + pip install "copier>=3.0,<4"Adjust the version range based on the project's actual copier dependency.
Makefile (1)
65-65: Consider using printf for consistency.Other informational messages in the Makefile use
printfwith color codes (e.g., lines 25, 32). For consistency, this echo could be replaced with a formatted printf.Apply this diff:
- echo "Run fmt, deptry, test and book" + @printf "$(GREEN)[INFO] Run fmt, deptry, test and book$(RESET)\n"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
.github/actions/setup-project/action.yml(3 hunks).github/workflows/book.yml(1 hunks).github/workflows/ci.yml(2 hunks).github/workflows/deptry.yml(1 hunks).github/workflows/marimo.yml(3 hunks).github/workflows/pre-commit.yml(1 hunks).github/workflows/sync.yml(2 hunks).gitignore(1 hunks).pre-commit-config.yaml(1 hunks)Makefile(1 hunks)Taskfile.yml(2 hunks)taskfiles/build.yml(3 hunks)taskfiles/cleanup.yml(1 hunks)taskfiles/docs.yml(8 hunks)taskfiles/quality.yml(1 hunks)tests/test_makefile.py(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- .github/workflows/deptry.yml
- .github/workflows/sync.yml
- .github/workflows/ci.yml
- .gitignore
🧰 Additional context used
🪛 Ruff (0.14.0)
tests/test_makefile.py
50-50: subprocess call: check for execution of untrusted input
(S603)
🔇 Additional comments (16)
taskfiles/cleanup.yml (2)
1-12: Good addition—documentation header aligns with template sync.The new header clearly documents the file's origin, purpose, and task components without modifying any functional logic. This complements the PR objective to sync template configurations.
19-29: No action needed — color variables are properly defined and accessible.The variables
BLUEandRESETare defined in the root Taskfile.yml under theenv:section (lines 29 and 36) and cleanup.yml is correctly included in the Taskfile. In Taskfile v3, environment variables defined at the root level are globally accessible to all included tasks, so the bash scripts in cleanup.yml will correctly expand these variables..github/workflows/book.yml (1)
44-61: Verify ./bin/task availability and error handling in workflow steps.The workflow correctly invokes setup-project before running task commands. Ensure that:
- The setup-project action completes successfully before step invocations
- Task failures result in workflow failure (default GitHub Actions behavior)
- The ./bin/task binary is available after setup-project completes
Confirm that setup-project installs ./bin/task and validates its presence before workflow proceeds.
.github/workflows/pre-commit.yml (1)
32-35: Verify pre-commit/action v3.0.1 compatibility and pre-commit availability.The workflow was simplified to use the official
pre-commit/action@v3.0.1, which replaces custom setup and invocation steps. Ensure that:
- The action is compatible with all hooks defined in
.pre-commit-config.yaml(ruff v0.14.1, markdownlint, actionlint, etc.)- The
pre-commitpackage is available in the ubuntu-latest runner environment- Python 3.12 is the correct and required version for this project's linters
Check the GitHub Actions runner image documentation to confirm pre-commit is pre-installed and compatible with the specified hooks.
taskfiles/docs.yml (1)
27-27: Verify build:install task dependency is safe and available.The test task adds a dependency on
./bin/task build:install. Ensure that:
- The build task can successfully set up ./bin/uv before subsequent commands run
- Multiple sequential calls to build:install do not conflict or fail
- Error handling is in place if build:install fails
Consider adding
set -eto the test task to fail fast on errors..github/workflows/marimo.yml (2)
52-58: Verify matrix generation handles edge cases correctly.The matrix generation logic uses a complex shell pipeline with
find,xargs, andjq. While it should work correctly, there are potential edge cases:
- Filenames with spaces or special characters:
find -print0 | xargs -0should handle these correctly- Empty notebook directory: correctly returns
matrix=[](line 54)- Files matching pattern: jq correctly filters out empty lines
The approach is functional but complex. Consider a simpler alternative if maintenance is a concern.
Test the matrix generation with:
- Empty
book/marimodirectory- Directory with 0-3 Python files
- Files with spaces or special characters in names
Confirm that the JSON array is correctly formatted and parsed.
85-85: Verify notebook execution with ./bin/uv run.The workflow executes each discovered notebook with
./bin/uv run "${{ matrix.notebook }}". Ensure that:
- Notebooks are valid Python scripts (not Marimo-specific syntax that requires
marimo run)- Exit codes are correctly propagated (pytest-style success/failure handling)
- The setup-project action provides all necessary dependencies for notebook execution
Confirm that test notebooks in
book/marimoare executable as standard Python scripts viapython <filename>..github/actions/setup-project/action.yml (2)
45-48: Security consideration: curl piping to shell scripts.Downloading and executing shell scripts via
curl | shis a common but risky pattern. Consider:
- Verifying script checksums (if available from source)
- Using
set -ein the downloaded scripts to fail fast- Downloading to a temp file, verifying, then executing (if feasible)
For now, this is acceptable for CI/CD environments, but be aware of the security implications.
Verify that Task and uv installation scripts are maintained by trusted sources and do not require additional verification beyond HTTPS.
86-97: Approve venv creation and dependency sync logic.The action correctly:
- Creates a virtual environment using ./bin/uv (line 88)
- Checks for pyproject.toml existence (line 93)
- Syncs dependencies with --all-extras only if pyproject.toml is present (line 94)
- Outputs pyproject_exists flag for downstream steps (lines 31-34)
This logic handles projects without pyproject.toml gracefully.
taskfiles/build.yml (2)
21-32: Approve conditional uv installation logic.The uv task correctly:
- Checks if ./bin/uv already exists and is executable (line 27)
- Skips reinstallation if present (good for idempotency)
- Installs via curl if missing, with error handling (lines 30-31)
The task is well-structured and appropriate as a dependency for the install task.
34-58: Verify --frozen flag is appropriate for lock file handling.The install task uses
./bin/uv sync --all-extras --frozen(line 54). The--frozenflag prevents updates to the lock file. Ensure that:
- The project maintains a lock file (uv.lock) in version control
- Lock file is intentionally not updated in CI/CD runs
- Lock file updates are done separately in a controlled manner
Confirm that the project uses uv.lock and that --frozen is the intended behavior for dependency installation.
.pre-commit-config.yaml (1)
12-12: ruff v0.14.1 is safe to use — no issues or regressions identified.The v0.14.1 release (2025-10-16) contains bug fixes addressing false positives/negatives in various linting rules, preview feature improvements, and binary size reductions. No breaking changes or compatibility issues are evident from the release notes. The update is appropriate for this patch bump.
Makefile (1)
22-37: Bootstrap logic looks solid.The install-task target properly ensures both go-task and uv are installed to
./bin, with appropriate checks to skip reinstallation and a final verification step. The conditional logic and error handling are well-structured.tests/test_makefile.py (3)
18-35: Excellent test isolation strategy.The autouse fixture properly isolates tests by copying only the Makefile to a temporary directory and restoring the working directory afterward. This prevents side effects and allows safe dry-run testing.
38-54: Helper function design is sound; static analysis warning is a false positive.The
run_makehelper correctly usessubprocess.runwithoutshell=True, and the-snflags ensure commands are shown but not executed. The S603 warning from Ruff is a false positive here—all inputs tosubprocess.runare controlled by the test code itself via theargsparameter, so there's no untrusted input risk.
60-121: Comprehensive dry-run validation coverage.The test methods effectively validate that each Makefile target produces the expected command sequences in dry-run mode. This approach is fast, avoids network calls, and provides good confidence that the Makefile wiring is correct.
| mkdir -p bin | ||
|
|
||
| # Install Task | ||
| curl -fsSL https://taskfile.dev/install.sh | sh -s -- -d -b ./bin | ||
|
|
||
| # Install uv and uvx | ||
| curl -fsSL https://astral.sh/uv/install.sh | UV_INSTALL_DIR="./bin" sh | ||
|
|
||
| # Verify installations | ||
| ./bin/task --version | ||
| ./bin/uv --version | ||
| ./bin/uvx --version |
There was a problem hiding this comment.
Add error handling and verification for binary downloads.
The setup script downloads Task, uv, and uvx via curl without explicit error handling. If any download fails, the script may continue with missing binaries.
Add explicit error checking after each curl command:
- name: Set up task, uv, uvx and the venv
shell: bash
run: |
mkdir -p bin
# Install Task
- curl -fsSL https://taskfile.dev/install.sh | sh -s -- -d -b ./bin
+ curl -fsSL https://taskfile.dev/install.sh | sh -s -- -d -b ./bin || { echo "Failed to install Task"; exit 1; }
# Install uv and uvx
- curl -fsSL https://astral.sh/uv/install.sh | UV_INSTALL_DIR="./bin" sh
+ curl -fsSL https://astral.sh/uv/install.sh | UV_INSTALL_DIR="./bin" sh || { echo "Failed to install uv"; exit 1; }
# Verify installations
./bin/task --version
./bin/uv --version
./bin/uvx --version🤖 Prompt for AI Agents
.github/actions/setup-project/action.yml lines 42-53: the script pipes downloads
into sh and runs verifications but lacks explicit error handling if a download
or install fails; update the flow to check the exit status of each curl before
piping to sh (or download to a temp file and verify checksum/size), and after
each install ensure the expected binary file exists and is executable
(./bin/task, ./bin/uv, ./bin/uvx); on any failure print a clear error message
identifying which download/install failed and exit with a non-zero status so the
action stops rather than continuing to verify or run missing binaries.
| - ./bin/task build:install | ||
| - printf " ${BLUE}[INFO] Start Marimo server with {{.MARIMO_FOLDER}}...${RESET}\n" | ||
| - | | ||
| if [ ! -d "{{.MARIMO_FOLDER}}" ]; then | ||
| printf " ${YELLOW}[WARN] Marimo folder '{{.MARIMO_FOLDER}}' not found, skipping start${RESET}\n" | ||
| else | ||
| uv pip install marimo | ||
| uv run marimo edit "{{.MARIMO_FOLDER}}" | ||
| ./bin/uv sync --all-extras | ||
| ./bin/uv run marimo edit "{{.MARIMO_FOLDER}}" |
There was a problem hiding this comment.
Potential issue with marimo task's ./bin/uv sync dependency.
The marimo task at line 171 calls ./bin/uv sync --all-extras but does not verify that ./bin/uv is available. If setup fails or PATH is not correctly set, this will fail with an unclear error.
The sequence should explicitly handle the case where ./bin/uv is not available. Consider combining the installer check and sync as:
cmds:
- ./bin/task build:install
- printf " ${BLUE}[INFO] Start Marimo server with {{.MARIMO_FOLDER}}...${RESET}\n"
- |
+ set -e
if [ ! -d "{{.MARIMO_FOLDER}}" ]; then
printf " ${YELLOW}[WARN] Marimo folder '{{.MARIMO_FOLDER}}' not found, skipping start${RESET}\n"
else
./bin/uv sync --all-extras
./bin/uv run marimo edit "{{.MARIMO_FOLDER}}"
fi📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - ./bin/task build:install | |
| - printf " ${BLUE}[INFO] Start Marimo server with {{.MARIMO_FOLDER}}...${RESET}\n" | |
| - | | |
| if [ ! -d "{{.MARIMO_FOLDER}}" ]; then | |
| printf " ${YELLOW}[WARN] Marimo folder '{{.MARIMO_FOLDER}}' not found, skipping start${RESET}\n" | |
| else | |
| uv pip install marimo | |
| uv run marimo edit "{{.MARIMO_FOLDER}}" | |
| ./bin/uv sync --all-extras | |
| ./bin/uv run marimo edit "{{.MARIMO_FOLDER}}" | |
| - ./bin/task build:install | |
| - printf " ${BLUE}[INFO] Start Marimo server with {{.MARIMO_FOLDER}}...${RESET}\n" | |
| - | | |
| set -e | |
| if [ ! -d "{{.MARIMO_FOLDER}}" ]; then | |
| printf " ${YELLOW}[WARN] Marimo folder '{{.MARIMO_FOLDER}}' not found, skipping start${RESET}\n" | |
| else | |
| ./bin/uv sync --all-extras | |
| ./bin/uv run marimo edit "{{.MARIMO_FOLDER}}" | |
| fi |
🤖 Prompt for AI Agents
In taskfiles/docs.yml around lines 165 to 172, the script calls ./bin/uv sync
--all-extras without verifying that ./bin/uv exists or is executable; add a
pre-check that ./bin/uv is present and executable (e.g., test -x ./bin/uv or
command -v ./bin/uv) and if missing either invoke the installer step (./bin/task
build:install) or emit a clear error and exit non-zero; ensure the check runs
before attempting sync and that any installer invocation is only attempted once
and its failure handled with a descriptive message.
This PR updates configuration files from
tschm/.config-templates@main.
Summary by CodeRabbit
Chores
Refactor
Tests