Skip to content

Verify runtime version in fedify init - #981

Open
userjmmm wants to merge 7 commits into
fedify-dev:mainfrom
userjmmm:issue-964-verify-runtime-version
Open

Verify runtime version in fedify init#981
userjmmm wants to merge 7 commits into
fedify-dev:mainfrom
userjmmm:issue-964-verify-runtime-version

Conversation

@userjmmm

@userjmmm userjmmm commented Aug 3, 2026

Copy link
Copy Markdown

Summary

Added runtime version verification to fedify init to enhance runtime safety by pre-checking minimum requirements.

Related issue

Changes

  • Added runtime minimum versions (minVersion) to json/rt.json, derived a RUNTIME list in const.ts, and added Runtime/Runtimes/RuntimeCheck types.
  • Added verifyRuntimeVersion, checkRuntimeVersion, resolveRequiredVersion, checkRuntimeRequirement, and checkAllRuntimes to lib.ts.
  • Added a minRuntimeVersions field to WebFrameworkDescription and set Astro's Node.js 22.12 requirement.
  • Updated ask/pm.ts to exit with an actionable error for an unsupported runtime in non-interactive mode, and to disable the affected package managers in the interactive menu.
  • Added tests for verifyRuntimeVersion and resolveRequiredVersion.

AI disclosure

Claude Code (claude-opus-4-8) assisted with this change: it proposed the design and drafted much of the implementation, tests, and this description. I reviewed and edited the work, made the design decisions, and verified the behaviour myself by running fedify init and the test suite.

Fedify has minimum runtime versions, and some frameworks require even
newer ones.  `fedify init` did not check this, so it could scaffold a
project on a runtime below the minimum, which can then fail at runtime.
Verify the selected runtime version before creating any files.

The base minimums (Deno 2.0.0, Node.js 22.0.0, Bun 1.1.0) mirror the
values declared by `@fedify/fedify` and are defined directly in
`rt.json`.  Frameworks with stricter requirements, such as Astro's
Node.js 22.12, raise the minimum through `minRuntimeVersions`.

Assisted-by: Claude Code:claude-opus-4-8
Cover `verifyRuntimeVersion` for versions below, equal to, and above the
minimum, and `resolveRequiredVersion` for framework overrides that raise
the base minimum.

Assisted-by: Claude Code:claude-opus-4-8
Assisted-by: Claude Code:claude-opus-4-8
@netlify

netlify Bot commented Aug 3, 2026

Copy link
Copy Markdown

Deploy Preview for fedify-json-schema canceled.

Name Link
🔨 Latest commit 1dd33c5
🔍 Latest deploy log https://app.netlify.com/projects/fedify-json-schema/deploys/6a73112b97804d0008bc3632

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

fedify init now validates Deno, Bun, and Node.js versions before project generation. It applies framework-specific minimums, classifies runtime failures, and updates explicit and interactive package-manager selection.

Changes

Runtime verification

Layer / File(s) Summary
Runtime contracts and requirements
packages/init/src/const.ts, packages/init/src/types.ts, packages/init/src/json/rt.json, packages/init/src/webframeworks/astro.ts
Defines runtime identifiers, minimum versions, validation result types, and Astro’s stricter Node.js requirement.
Runtime validation engine
packages/init/src/lib.ts, packages/init/src/lib.test.ts
Parses runtime command output, compares versions, resolves framework requirements, classifies failures, and checks runtimes concurrently.
Initializer package-manager flow
packages/init/src/ask/pm.ts, CHANGES.md, changes.d/init/verify-runtime-version.md
Validates explicit and interactive package-manager choices and documents runtime verification behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested labels: type/enhancement, component/cli, runtime/node, runtime/bun

Suggested reviewers: dahlia, 2chanhaeng

Sequence Diagram(s)

sequenceDiagram
  participant FedifyInit
  participant fillPackageManager
  participant checkAllRuntimes
  participant RuntimeCommands
  FedifyInit->>fillPackageManager: resolve package manager
  fillPackageManager->>checkAllRuntimes: validate runtime requirements
  checkAllRuntimes->>RuntimeCommands: execute version commands
  RuntimeCommands-->>checkAllRuntimes: return runtime statuses
  checkAllRuntimes-->>fillPackageManager: return compatible options
  fillPackageManager-->>FedifyInit: continue or exit
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% 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
Title check ✅ Passed The title clearly summarizes the main change: runtime version verification during fedify init.
Description check ✅ Passed The description directly explains the runtime validation changes, affected flows, tests, and linked issue.
Linked Issues check ✅ Passed The changes address shared runtime minimums, Deno/Node.js/Bun checks, framework overrides, error handling, interactive behavior, and version tests required by #964.
Out of Scope Changes check ✅ Passed The changes are limited to runtime metadata, validation logic, initialization behavior, tests, and changelog documentation related to #964.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/init/src/ask/pm.ts`:
- Around line 40-64: Update the explicit package-manager branch before its
availability/runtime checks to validate isWfSupportsPm(options.webFramework,
pm), matching the interactive selection path. Reject unsupported combinations
using the existing error/exit behavior, while preserving the current checks and
successful return for compatible package managers.
- Around line 53-55: Update the result.status === "missing" branch to include
actionable runtime installation guidance, using runtimes[pmToRt(pm)].label and
an install URL. Extend the installer metadata or add a runtime helper to support
the getInstallUrl signature needed for this path, while preserving the existing
missing-runtime error message.

In `@packages/init/src/lib.ts`:
- Around line 221-224: Update the return type of checkRuntimeVersion to use the
imported RuntimeCheck type instead of redeclaring the equivalent union, matching
checkRuntimeRequirement and keeping the shared contract centralized.
- Around line 239-249: Update checkRuntimeVersion so unexpected runtime-check
errors are converted into the same result shape used for missing, unsupported,
and malformed runtimes instead of being rethrown. Ensure checkAllRuntimes and
askPackageManager handle that result by printing an actionable CLI message and
exiting cleanly, while preserving the existing not-found behavior.
🪄 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: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6e67122f-54e4-4ac4-a1fb-5b08cbe4b156

📥 Commits

Reviewing files that changed from the base of the PR and between a681e1f and c4cdc1c.

📒 Files selected for processing (9)
  • CHANGES.md
  • changes.d/init/verify-runtime-version.md
  • packages/init/src/ask/pm.ts
  • packages/init/src/const.ts
  • packages/init/src/json/rt.json
  • packages/init/src/lib.test.ts
  • packages/init/src/lib.ts
  • packages/init/src/types.ts
  • packages/init/src/webframeworks/astro.ts

Comment thread packages/init/src/ask/pm.ts Outdated
Comment thread packages/init/src/ask/pm.ts Outdated
Comment on lines +53 to +55
if (result.status === "missing") {
printErrorMessage`The runtime for package manager ${pm} is missing.`;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check how getInstallUrl and noticeInstallUrl are used across pm.ts.
set -euo pipefail

fd 'pm.ts' packages/init/src/ask | xargs cat -n

Repository: fedify-dev/fedify

Length of output: 5877


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "## candidate lib.ts files"
fd 'lib\.ts$' packages/init/src/ask | sort

echo
echo "## imports/usages of getInstallUrl pmToRt"
rg -n "getInstallUrl|pmToRt|runtimes|checkRuntimeRequirement|checkAllRuntimes" packages/init/src/ask -g '*.ts'

echo
echo "## runtime definitions/usages"
rg -n "export const runtimes|const runtimes|getInstallUrl\s*=" packages/init/src/ask packages/init/src -g '*.ts' | head -200

Repository: fedify-dev/fedify

Length of output: 1198


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "## packages/init/src/lib.ts around definitions"
sed -n '1,180p' packages/init/src/lib.ts | cat -n

echo
echo "## packages/init/src/types.ts runtime/package manager shape"
sed -n '1,260p' packages/init/src/types.ts | cat -n

echo
echo "## packages/init/src/webframeworks/utils.ts relevant lines"
sed -n '1,180p' packages/init/src/webframeworks/utils.ts | cat -n

echo
echo "## runtime install mappings"
rg -n "install|version|version\\]" packages/init/src -g '*.ts' | head -200

Repository: fedify-dev/fedify

Length of output: 29590


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "## rt.json"
python3 - <<'PY'
import json
from pathlib import Path
p = Path("packages/init/src/json/rt.json")
data = json.loads(p.read_text())
print(json.dumps(data, indent=2))
PY

echo
echo "## pmToRt behavior"
python3 - <<'PY'
def pm_to_rt(pm):
    return "node" if pm not in {"deno", "bun"} else pm
for pm in ["deno", "bun", "npm", "pnpm", "yarn"]:
    print(f"{pm} -> {pm_to_rt(pm)}")
PY

Repository: fedify-dev/fedify

Length of output: 779


Show an install link for missing runtimes.

The “missing runtime” path exits with only printErrorMessage and no actionable install guidance, unlike the package-manager-missing path. Use the runtime label via runtimes[pmToRt(pm)].label and print an install link, extending the installer metadata or adding a runtime helper for the unsupported getInstallUrl signature.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/init/src/ask/pm.ts` around lines 53 - 55, Update the result.status
=== "missing" branch to include actionable runtime installation guidance, using
runtimes[pmToRt(pm)].label and an install URL. Extend the installer metadata or
add a runtime helper to support the getInstallUrl signature needed for this
path, while preserving the existing missing-runtime error message.

Comment thread packages/init/src/lib.ts Outdated
Comment thread packages/init/src/lib.ts

@2chanhaeng 2chanhaeng 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.

Great work! Thanks for your contribution to Fedify. Before merging this PR, some changes are needed, and I have left suggestions to make your PR better. Please read them and consider applying them!

Comment thread CHANGES.md Outdated
Comment thread packages/init/src/lib.ts Outdated
Comment thread packages/init/src/lib.ts Outdated
Comment thread packages/init/src/ask/pm.ts Outdated
Comment on lines +97 to +111
const reason = !isWfSupportsPm(wf, value)
? `not supported with ${webFrameworks[wf].label}`
: check.status === "unsupported"
? `requires ${label} ${check.required} or later`
: check.status === "missing"
? `requires ${label} which is not installed`
: check.status === "malformed"
? `could not detect ${label} version`
: "";
const disabled = !isWfSupportsPm(wf, value) || check.status !== "ok";
return {
name: disabled ? `${value} (${reason})` : value,
value,
disabled,
};

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.

It would be better const reason = /* ... */ : ""; return disabled === "" ? { name, value } : { name, value, disabled } because select from @inquirer/prompts show disabled if it is string.

Comment thread packages/init/src/ask/pm.ts
Comment thread packages/init/src/ask/pm.ts Outdated
`askPackageManager` recomputed the runtime checks through
`checkAllRuntimes` every time it built the prompt.  Following the
review, that computation was separated into `calculateChoices` to run
once.  When `fillPackageManager` already has a `packageManager`, it now
looks the value up in `choices` instead of calling
`checkRuntimeRequirement` again.

`checkRuntimeRequirement` is no longer used outside `lib.ts`, so its
export was removed.

Assisted-by: Claude Code:claude-opus-4-8
When the chosen package manager was not installed, `fillPackageManager`
recursed to prompt again, recomputing `calculateChoices` on every retry,
so replace the recursion with a loop that reuses the `choices` computed
once at the start.

Assisted-by: Claude Code:claude-opus-4-8

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
CHANGES.md (1)

183-195: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Correct the PR reference.

Line 183 escapes the closing citation bracket. Line 195 links PR #981 as an issue. Remove the escape and change the reference URL to https://github.com/fedify-dev/fedify/pull/981.

Based on PR objectives: this change is PR #981.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CHANGES.md` around lines 183 - 195, In CHANGES.md, correct the PR `#981`
citation by removing the unnecessary escape from its closing bracket, and update
the `#981` reference URL from the issues endpoint to the pull endpoint. Leave the
other changelog references unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@CHANGES.md`:
- Around line 183-195: In CHANGES.md, correct the PR `#981` citation by removing
the unnecessary escape from its closing bracket, and update the `#981` reference
URL from the issues endpoint to the pull endpoint. Leave the other changelog
references unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 408742d3-7138-47d9-9b17-033403cf539d

📥 Commits

Reviewing files that changed from the base of the PR and between c4cdc1c and 1dd33c5.

📒 Files selected for processing (4)
  • CHANGES.md
  • changes.d/init/verify-runtime-version.md
  • packages/init/src/ask/pm.ts
  • packages/init/src/lib.ts

@userjmmm

userjmmm commented Aug 5, 2026

Copy link
Copy Markdown
Author

I applied changes. Could you take another look?

@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 27.48092% with 95 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
packages/init/src/ask/pm.ts 8.47% 54 Missing ⚠️
packages/init/src/lib.ts 40.57% 41 Missing ⚠️
Files with missing lines Coverage Δ
packages/init/src/const.ts 100.00% <100.00%> (ø)
packages/init/src/webframeworks/astro.ts 100.00% <100.00%> (ø)
packages/init/src/lib.ts 61.53% <40.57%> (-5.13%) ⬇️
packages/init/src/ask/pm.ts 32.35% <8.47%> (-18.53%) ⬇️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

Verify runtime is supported version when fedify init

2 participants