Skip to content

chore: modernize to latest rainix (flake + CI)#141

Open
thedavidmeister wants to merge 8 commits into
mainfrom
2026-06-03-modernize-rainix
Open

chore: modernize to latest rainix (flake + CI)#141
thedavidmeister wants to merge 8 commits into
mainfrom
2026-06-03-modernize-rainix

Conversation

@thedavidmeister

@thedavidmeister thedavidmeister commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

dotrain's flake no longer evaluated against latest rainix (referenced the removed rainix-rs-prelude/rainix-rs-test/rainix-rs-artifacts package attrs), and its CI used the discontinued magic-nix-cache action + removed tasks.

  • flake: github:rainlanguage/rainix + lock bump; drop removed-attr devShell refs; base on rainix.devShells.rust-node-shell (rust + node + wasm-bindgen) keeping the dotrain binary + build/test/js-bindings-docs tasks. Verified nix develop resolves (cargo 1.94, node 22, wasm-bindgen).
  • CI (rainix.yaml): reusable rainix-rs-static + rainix-rs-test + a js-bindings job (build/test/docs). wasm-test is intentionally omitted — the CLI isn't wasm-targeted; the js bindings are the wasm path (built via npm/wasm-pack).
  • manual-release: dead magic-nix-cachecache-nix-action; drop removed rainix-rs-prelude; rainix-rs-testcargo test.
  • formatter hooks applied (taplo/denofmt/rustfmt).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Refreshed README tutorials and Composer/LSP documentation formatting, including updated JS/TS examples and expanded build instructions.
  • Chores
    • Updated lint/formatting configuration and refined CI workflows, including adding an automated package release workflow.
  • Tests
    • Improved completion test utilities with optional order-insensitive assertions for more stable namespace-related tests.
  • Refactor
    • Streamlined development shell configuration and improved JS/WebAssembly bootstrapping behavior for CJS/ESM builds.

- flake: point at github:rainlanguage/rainix; bump lock; drop the removed
  rainix-rs-prelude/test/artifacts devShell refs (flake no longer evaluated
  against latest rainix); base the shell on rainix.devShells.rust-node-shell
  (rust + node + wasm-bindgen) while keeping the dotrain binary + js-binding tasks
- CI: replace bespoke rainix.yaml (dead magic-nix-cache, removed tasks) with
  reusable rainix-rs-static + rainix-rs-test + a js-bindings job; drop wasm-test
  (the cli isn't wasm-targeted; js bindings are built via npm/wasm-pack)
- manual-release: swap dead magic-nix-cache for cache-nix-action, drop the
  removed rainix-rs-prelude, rainix-rs-test -> cargo test
- apply latest rainix formatter hooks (taplo/denofmt/rustfmt config)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@thedavidmeister, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 51 minutes and 4 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b836a9b3-e99d-407d-809f-1468ae7a7eaa

📥 Commits

Reviewing files that changed from the base of the PR and between 809dc5a and 76df6f1.

📒 Files selected for processing (1)
  • crates/dotrain/src/parser/raindocument/mod.rs

Walkthrough

Migrates six Rust WASM types from a value-consuming Result-returning TryFromJsValue to a reference-based Option-returning try_from_js_value_ref. Fixes JS wasm bootstrapping variable naming and ESM instantiation style. Refactors Nix flake to use rust-node-shell from the renamed rainlanguage/rainix org. Restructures GitHub Actions workflows and adds new package-release automation. Adds unordered completion test comparison and refreshes README documentation.

Changes

Rust wasm-bindgen migration, JS/TS fixes, CI/Nix refactor, and docs

Layer / File(s) Summary
TryFromJsValue migration to reference-based Option form
crates/dotrain/src/types/impls.rs, crates/dotrain/src/js_api/raindocument.rs, crates/dotrain/src/types/ast.rs, crates/dotrain/src/composer/mod.rs, crates/dotrain/src/cli/mod.rs, crates/dotrain/src/parser/raindocument/mod.rs, .rustfmt.toml
Removes serde_wasm_bindgen::Error imports and replaces JsValue-consuming Result-returning TryFromJsValue impls with try_from_js_value_ref(&JsValue) -> Option<Self> across Problem, ParsedItem, Comment, Import, Binding, RainlangSource, and Rebind. Adds #[allow(clippy::large_enum_variant)] to BindingItem and NamespaceItem, #[allow(mismatched_lifetime_syntaxes)] to build_targets_sourcemap, removes unused clap::command import, switches a test fixture from vec![...] to [...], and enables unstable_features in rustfmt.
JS/TS wasm bootstrap, completion test ordering, and tooling config
scripts/prepare.js, test/completion.test.ts, .eslintrc.json, package.json, crates/dotrain/Cargo.toml, crates/lsp/Cargo.toml
Changes scripts/prepare.js CJS wasm loading to use wasmBytes variable and ESM instantiation to assignment-based form. Adds unordered parameter to testCompletion helper with sort-based comparison, applied to two namespace completion tests. Removes prettier/prettier ESLint rule, adds @typescript-eslint/no-empty-function. Reorders package.json devDependencies. Reformats js-api feature and tsify dependency arrays in both Cargo.toml files.
Nix flake refactor and GitHub Actions CI/release workflow updates
flake.nix, .github/workflows/rainix.yaml, .github/workflows/pr-assessment.yaml, .github/workflows/package-release.yaml
Switches flake.nix rainix input to github:rainlanguage/rainix, simplifies devShells.default via inputsFrom and inherited shellHook from rust-node-shell. Replaces the matrix rainix CI job with separate static, test reusable-workflow calls and a js-bindings job. Adds new package-release.yaml workflow that publishes dotrain, dotrain-lsp crates and @rainlanguage/dotrain npm package on main pushes via the rainix-autopublish reusable workflow. Removes blank line in pr-assessment.yaml.
README documentation refresh
README.md
Expands the project introduction with bullet formatting and external links, updates the JS/TS tutorial to show newRainDocument and compose, adds a dotrain_lsp crate section with install command and js-api feature, and reformats CLI and JS/TS bindings build instructions with explicit nix develop -c command lines.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.65% 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 'chore: modernize to latest rainix (flake + CI)' directly aligns with the PR's main objectives of updating flake and CI workflow to work with latest rainix.
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 2026-06-03-modernize-rainix

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.

thedavidmeister and others added 3 commits June 3, 2026 05:32
- remove unused clap::command import
- useless vec! -> array in a test fixture
- #[allow(clippy::large_enum_variant)] on AST enums BindingItem/NamespaceItem
  (boxing variants is an invasive representation change; left for maintainer)
- #[allow(mismatched_lifetime_syntaxes)] on build_targets_sourcemap (new 1.94 lint)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The modernized rainix flake ships wasm-bindgen-cli 0.2.122, so the crate
and the generated bindings are brought in line with it:

- pin wasm-bindgen 0.2.122 in Cargo.lock to match the CLI schema version
- update the hand-written TryFromJsValue impls to the 0.2.122 trait shape
  (try_from_js_value_ref returning Option, no associated Error type)
- scripts/prepare: match the 0.2.122 nodejs glue preamble when embedding
  the wasm as base64, and assign the wasm-bindgen-declared module/instance
  bindings in the esm loader instead of redeclaring them
- drop prettier, eslint-plugin-prettier and eslint-config-prettier and the
  prettier eslint integration; rainix supplies prettier via its pre-commit
  bundle and the no-consumer-prettier hook forbids consumer-side prettier
- silence @typescript-eslint/no-empty-function on the generated bindings,
  alongside the already-disabled base no-empty-function rule
- compare namespace completion suggestions as a set, since namespace items
  come from an unordered map and their suggestion order is not significant

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The rainix-rs reusable callers (static, test) gain `secrets: inherit` so
the shared Cachix substituter is reachable. The js-bindings job drops its
hand-rolled nix-quick-install + cache-nix preamble (which omitted Cachix)
for the rainix nix-cachix-setup + rust-cache composites that every rainix
reusable uses. The build/test/docs commands stay: they are dotrain flake
devShell tasks (npm + wasm-bindgen CLI over the js-api crate, mocha tests,
api-extractor docs) with no matching rainix reusable workflow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@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

Caution

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

⚠️ Outside diff range comments (2)
.github/workflows/manual-release.yaml (2)

2-3: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add workflow concurrency for manual release operations.

This workflow mutates tags/releases and publishes packages. Without a concurrency group, overlapping manual runs can race on versioning, tagging, and publish steps.

Suggested safeguard
 name: Manual Release
 on:
   workflow_dispatch:
@@
+concurrency:
+  group: manual-release-${{ github.ref }}
+  cancel-in-progress: false
 jobs:
   release:

Also applies to: 17-19

🤖 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 @.github/workflows/manual-release.yaml around lines 2 - 3, Add workflow
concurrency configuration to prevent simultaneous manual release runs from
racing on versioning, tagging, and publishing. After the workflow_dispatch
trigger in the on section, add a concurrency group that uses a fixed identifier
(such as the workflow name or a release-specific label) with cancel-in-progress
set to true to ensure that if multiple manual release runs are triggered, only
the latest one executes and any in-progress runs are cancelled.

Source: Linters/SAST tools


20-22: ⚠️ Potential issue | 🟠 Major

Use step outputs, not environment variables, for job-level outputs.

release.outputs.version must be sourced from a step output (via $GITHUB_OUTPUT), not from ${{ env.NEW_VERSION }}. Environment variables written to $GITHUB_ENV are not accessible across job boundaries. This causes release_bin to receive an empty or undefined version value when it references ${{ needs.release.outputs.version }}, breaking artifact naming and tag operations downstream.

Proposed fix
   release:
     runs-on: ubuntu-latest
     outputs:
-      version: ${{ env.NEW_VERSION }}
+      version: ${{ steps.set_version.outputs.new_version }}
     steps:
       - uses: actions/checkout@v4
         with:
           fetch-depth: 0
           submodules: recursive
           ssh-key: ${{ secrets.PUBLISHER_SSH_KEY }}
       - uses: nixbuild/nix-quick-install-action@v30
         with:
           nix_conf: |
             keep-env-derivations = true
             keep-outputs = true
       - name: Restore and save Nix store
         uses: nix-community/cache-nix-action@v6
         with:
           primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
           restore-prefixes-first-match: nix-${{ runner.os }}-
           gc-max-store-size-linux: 1G
       - name: Install NodeJS v22
         uses: actions/setup-node@v4
         with:
           node-version: 22
           cache: 'npm'
       - name: Run rainix-rs-test
         run: nix develop -c cargo test
       - name: Build JS Bindings
         run: nix develop -c build-js-bindings
       - name: Run JS Tests
         run: nix develop -c test-js-bindings
       - name: Git Config
         run: |
           git config --global user.email "${{ secrets.CI_GIT_EMAIL }}"
           git config --global user.name "${{ secrets.CI_GIT_USER }}"
       - name: Publish to crates.io
         run: nix develop -c cargo release --no-confirm --execute --no-tag --workspace ${{ inputs.version-level }}
         env:
           CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
       # set npm version to rust crate version
       - name: Set Version
+        id: set_version
-        run: echo "NEW_VERSION=$(nix develop -c npm version $(node ./scripts/version.js) --no-git-tag-version)" >> $GITHUB_ENV
+        run: |
+          NEW_VERSION="$(nix develop -c npm version "$(node ./scripts/version.js)" --no-git-tag-version)"
+          echo "NEW_VERSION=$NEW_VERSION" >> "$GITHUB_ENV"
+          echo "new_version=$NEW_VERSION" >> "$GITHUB_OUTPUT"

Applies to lines 20–21 and 59–60.

🤖 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 @.github/workflows/manual-release.yaml around lines 20 - 22, The job-level
outputs definition is incorrectly using environment variables instead of step
outputs. Replace the current approach where NEW_VERSION is written to
$GITHUB_ENV with a step-based approach that writes to $GITHUB_OUTPUT. Update the
outputs section at line 20 to source the version from a step output reference
(using the format ${{ steps.{step_id}.outputs.version }}) instead of ${{
env.NEW_VERSION }}. Identify where NEW_VERSION is being set (around line 59-60)
and modify that step to write the version to $GITHUB_OUTPUT with the appropriate
format, ensuring the step has an id attribute so it can be referenced in the
outputs section. This fix is needed at both the output definition location
(lines 20-21) and wherever NEW_VERSION is being set (lines 59-60) to ensure the
version value is properly accessible to downstream jobs like release_bin.
🤖 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 @.github/workflows/rainix.yaml:
- Around line 1-3: The rainix-rs workflow in .github/workflows/rainix.yaml lacks
explicit permission declarations, relying on default GITHUB_TOKEN permissions
which can drift over time. Add a top-level `permissions` section immediately
after the `on` trigger declaration to declare only the minimal scopes required
for this CI workflow. Since this is a read-only build/test workflow, set
permissions to read-only at the workflow level (such as read for contents,
packages, and id-token if needed), and override specific jobs only if they
require different permissions. This follows the principle of least privilege and
prevents unintended permission escalation.
- Around line 5-22: Pin all GitHub Actions and reusable workflow references to
immutable full commit SHAs instead of mutable refs. In
.github/workflows/rainix.yaml (lines 5, 8, 19, 22), replace all `@main`
references in rainix-rs-static.yaml, rainix-rs-test.yaml, nix-cachix-setup, and
rust-cache with their corresponding full commit SHAs. In
.github/workflows/manual-release.yaml (lines 23-40, 80, 87, 145), replace all
semver tag references including `actions/checkout@v4`,
`nixbuild/nix-quick-install-action@v30`, `nix-community/cache-nix-action@v6`,
`actions/setup-node@v4`, `JS-DevTools/npm-publish@v1`, and
`softprops/action-gh-release@v2` with their full commit SHAs to prevent upstream
drift and supply-chain vulnerabilities.

In `@README.md`:
- Around line 5-11: Fix two text issues in the README.md introduction section:
correct the spelling of "broswers" to "browsers" on line 8, and update the
capitalization of "Typescript/Javascript" to "TypeScript/JavaScript" on line 10
to follow standard naming conventions for these languages.
- Around line 13-22: The README.md file uses bare "[here]" as link text in three
locations (lines 14, 16, and 22), which violates accessibility best practices.
Replace each instance with descriptive link text that clearly conveys the
destination: for the Dotrain specs link on line 14, use text like "Dotrain
specifications"; for the Rainlang specs link on line 16, use "Rainlang
specifications"; and for the vscode extension marketplace link on line 22, use
descriptive text like "Dotrain vscode extension on Visual Studio Marketplace" or
similar that indicates the actual resource being linked.

---

Outside diff comments:
In @.github/workflows/manual-release.yaml:
- Around line 2-3: Add workflow concurrency configuration to prevent
simultaneous manual release runs from racing on versioning, tagging, and
publishing. After the workflow_dispatch trigger in the on section, add a
concurrency group that uses a fixed identifier (such as the workflow name or a
release-specific label) with cancel-in-progress set to true to ensure that if
multiple manual release runs are triggered, only the latest one executes and any
in-progress runs are cancelled.
- Around line 20-22: The job-level outputs definition is incorrectly using
environment variables instead of step outputs. Replace the current approach
where NEW_VERSION is written to $GITHUB_ENV with a step-based approach that
writes to $GITHUB_OUTPUT. Update the outputs section at line 20 to source the
version from a step output reference (using the format ${{
steps.{step_id}.outputs.version }}) instead of ${{ env.NEW_VERSION }}. Identify
where NEW_VERSION is being set (around line 59-60) and modify that step to write
the version to $GITHUB_OUTPUT with the appropriate format, ensuring the step has
an id attribute so it can be referenced in the outputs section. This fix is
needed at both the output definition location (lines 20-21) and wherever
NEW_VERSION is being set (lines 59-60) to ensure the version value is properly
accessible to downstream jobs like release_bin.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 609efcff-142d-498f-a7c9-6e36186025cd

📥 Commits

Reviewing files that changed from the base of the PR and between 34ab3e7 and d79cab0.

⛔ Files ignored due to path filters (3)
  • Cargo.lock is excluded by !**/*.lock
  • flake.lock is excluded by !**/*.lock
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (18)
  • .eslintrc.json
  • .github/workflows/manual-release.yaml
  • .github/workflows/pr-assessment.yaml
  • .github/workflows/rainix.yaml
  • .rustfmt.toml
  • README.md
  • crates/dotrain/Cargo.toml
  • crates/dotrain/src/cli/mod.rs
  • crates/dotrain/src/composer/mod.rs
  • crates/dotrain/src/js_api/raindocument.rs
  • crates/dotrain/src/parser/raindocument/mod.rs
  • crates/dotrain/src/types/ast.rs
  • crates/dotrain/src/types/impls.rs
  • crates/lsp/Cargo.toml
  • flake.nix
  • package.json
  • scripts/prepare.js
  • test/completion.test.ts
💤 Files with no reviewable changes (2)
  • package.json
  • .github/workflows/pr-assessment.yaml

Comment on lines +1 to 3
name: rainix-rs
on: [push]

jobs:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Declare explicit least-privilege permissions.

This workflow currently relies on default GITHUB_TOKEN permissions for all jobs. Set explicit minimal scopes (for this CI workflow, typically read-only) to avoid permission drift.

Suggested hardening
 name: rainix-rs
 on: [push]
+permissions:
+  contents: read
 jobs:
   static:
📝 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.

Suggested change
name: rainix-rs
on: [push]
jobs:
name: rainix-rs
on: [push]
permissions:
contents: read
jobs:
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 1-26: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)


[warning] 2-2: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting

(concurrency-limits)

🤖 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 @.github/workflows/rainix.yaml around lines 1 - 3, The rainix-rs workflow in
.github/workflows/rainix.yaml lacks explicit permission declarations, relying on
default GITHUB_TOKEN permissions which can drift over time. Add a top-level
`permissions` section immediately after the `on` trigger declaration to declare
only the minimal scopes required for this CI workflow. Since this is a read-only
build/test workflow, set permissions to read-only at the workflow level (such as
read for contents, packages, and id-token if needed), and override specific jobs
only if they require different permissions. This follows the principle of least
privilege and prevents unintended permission escalation.

Source: Linters/SAST tools

Comment on lines +5 to +22
uses: rainlanguage/rainix/.github/workflows/rainix-rs-static.yaml@main
secrets: inherit
test:
uses: rainlanguage/rainix/.github/workflows/rainix-rs-test.yaml@main
secrets: inherit
js-bindings:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Shared rainix nix + cachix CI preamble (checkout, nix-quick-install,
# Cachix, cache-nix-action) — the pinned action SHAs live once in the
# composite, matching every rainix reusable. The build/test/docs commands
# below are dotrain-specific flake devShell tasks (npm + wasm-bindgen CLI
# over the js-api crate, mocha tests, api-extractor docs), so there is no
# rainix reusable workflow that runs them; only the preamble is shared.
- uses: rainlanguage/rainix/.github/actions/nix-cachix-setup@main
with:
submodules: recursive
fetch-depth: 0

- uses: DeterminateSystems/nix-installer-action@v4
- uses: DeterminateSystems/magic-nix-cache-action@v2

- run: nix develop -c rainix-rs-prelude

- name: Run ${{ matrix.task }}
run: nix develop -c ${{ matrix.task }}

- name: Build JS Bindings
run: nix develop -c build-js-bindings

- name: Run JS Tests
run: nix develop -c test-js-bindings

- name: Test JS Doc Generation
run: nix develop -c js-bindings-docs No newline at end of file
cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }}
- uses: rainlanguage/rainix/.github/actions/rust-cache@main

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find .github/workflows -type f -name "*.yaml" -o -name "*.yml" | head -20

Repository: rainlanguage/dotrain

Length of output: 169


🏁 Script executed:

cat -n .github/workflows/rainix.yaml

Repository: rainlanguage/dotrain

Length of output: 1354


🏁 Script executed:

cat -n .github/workflows/manual-release.yaml

Repository: rainlanguage/dotrain

Length of output: 6932


Pin all action and reusable workflow references to immutable commit SHAs, not @main or semver tags. This prevents upstream ref drift and supply-chain attacks in trusted CI and release paths.

  • .github/workflows/rainix.yaml (lines 5, 8, 19, 22): Replace @main refs with full commit SHAs for both reusable workflows and actions.
  • .github/workflows/manual-release.yaml: Pin all actions—including actions/checkout@v4, nixbuild/nix-quick-install-action@v30, nix-community/cache-nix-action@v6, actions/setup-node@v4, JS-DevTools/npm-publish@v1, and softprops/action-gh-release@v2 (lines 23–40, 80, 87, 145)—to commit SHAs. Semver tags like @v4 remain mutable and can be rewritten by maintainers.
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 7-9: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)


[error] 5-5: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 8-8: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 19-19: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 22-22: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[warning] 5-5: secrets unconditionally inherited by called workflow (secrets-inherit): this reusable workflow

(secrets-inherit)


[warning] 8-8: secrets unconditionally inherited by called workflow (secrets-inherit): this reusable workflow

(secrets-inherit)


[info] 10-10: workflow or action definition without a name (anonymous-definition): this job

(anonymous-definition)

📍 Affects 2 files
  • .github/workflows/rainix.yaml#L5-L22 (this comment)
  • .github/workflows/manual-release.yaml#L23-L40
🤖 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 @.github/workflows/rainix.yaml around lines 5 - 22, Pin all GitHub Actions
and reusable workflow references to immutable full commit SHAs instead of
mutable refs. In .github/workflows/rainix.yaml (lines 5, 8, 19, 22), replace all
`@main` references in rainix-rs-static.yaml, rainix-rs-test.yaml,
nix-cachix-setup, and rust-cache with their corresponding full commit SHAs. In
.github/workflows/manual-release.yaml (lines 23-40, 80, 87, 145), replace all
semver tag references including `actions/checkout@v4`,
`nixbuild/nix-quick-install-action@v30`, `nix-community/cache-nix-action@v6`,
`actions/setup-node@v4`, `JS-DevTools/npm-publish@v1`, and
`softprops/action-gh-release@v2` with their full commit SHAs to prevent upstream
drift and supply-chain vulnerabilities.

Source: Linters/SAST tools

Comment thread README.md
Comment on lines +5 to +11
The Rain language server protocol
([LSP](https://microsoft.github.io/language-server-protocol/)) services
implementation (language services) and .rain composer written in rust and made
available for NodeJs and broswers through
[wasm-bindgen](https://rustwasm.github.io/docs/wasm-bindgen/) in
Typescript/Javascript which makes it well suited for editors and IDEs (as it is
used in Rainlang vscode and codemirror language extension).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix spelling and capitalization in introduction.

Line 8 contains a typo: "broswers" should be "browsers". Line 10 should follow standard capitalization: "TypeScript/JavaScript" instead of "Typescript/Javascript".

📝 Proposed fix
- available for NodeJs and broswers through
+ available for NodeJs and browsers through

- Typescript/Javascript which makes it well suited for editors and IDEs (as it is
+ TypeScript/JavaScript which makes it well suited for editors and IDEs (as it is
📝 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.

Suggested change
The Rain language server protocol
([LSP](https://microsoft.github.io/language-server-protocol/)) services
implementation (language services) and .rain composer written in rust and made
available for NodeJs and broswers through
[wasm-bindgen](https://rustwasm.github.io/docs/wasm-bindgen/) in
Typescript/Javascript which makes it well suited for editors and IDEs (as it is
used in Rainlang vscode and codemirror language extension).
The Rain language server protocol
([LSP](https://microsoft.github.io/language-server-protocol/)) services
implementation (language services) and .rain composer written in rust and made
available for NodeJs and browsers through
[wasm-bindgen](https://rustwasm.github.io/docs/wasm-bindgen/) in
TypeScript/JavaScript which makes it well suited for editors and IDEs (as it is
used in Rainlang vscode and codemirror language extension).
🧰 Tools
🪛 LanguageTool

[grammar] ~8-~8: Ensure spelling is correct
Context: ... rust and made available for NodeJs and broswers through [wasm-bindgen](https://rustwasm...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~10-~10: Use a hyphen to join words.
Context: ...ypescript/Javascript which makes it well suited for editors and IDEs (as it is us...

(QB_NEW_EN_HYPHEN)

🤖 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 `@README.md` around lines 5 - 11, Fix two text issues in the README.md
introduction section: correct the spelling of "broswers" to "browsers" on line
8, and update the capitalization of "Typescript/Javascript" to
"TypeScript/JavaScript" on line 10 to follow standard naming conventions for
these languages.

Comment thread README.md
Comment on lines +13 to +22
- Dotrain specs can be found
[here](https://github.com/rainlanguage/specs/blob/main/dotrain.md)
- Rainlang specs can be found
[here](https://github.com/rainlanguage/specs/blob/main/rainlang.md)
- Dotrain has been implemented for vscode and codemirror, see
[rainlang-vscode](https://github.com/rainlanguage/rainlang-vscode) and
[rainlang-codemirror](https://github.com/rainlanguage/rainlang-codemirror)
repositories for more details.
- Dotrain vscode extension can be found
[here](https://marketplace.visualstudio.com/items?itemName=rainprotocol.rainlang-vscode).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Improve link text descriptiveness.

Lines 14, 16, and 22 use bare "[here]" as link text, which is not user-friendly and fails accessibility best practices. Replace each with a descriptive label that conveys what the link contains.

📝 Proposed fix
- - Dotrain specs can be found
-   [here](https://github.com/rainlanguage/specs/blob/main/dotrain.md)
+ - [Dotrain specs](https://github.com/rainlanguage/specs/blob/main/dotrain.md)

- - Rainlang specs can be found
-   [here](https://github.com/rainlanguage/specs/blob/main/rainlang.md)
+ - [Rainlang specs](https://github.com/rainlanguage/specs/blob/main/rainlang.md)

- - Dotrain vscode extension can be found
-   [here](https://marketplace.visualstudio.com/items?itemName=rainprotocol.rainlang-vscode).
+ - [Dotrain vscode extension](https://marketplace.visualstudio.com/items?itemName=rainprotocol.rainlang-vscode)
📝 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.

Suggested change
- Dotrain specs can be found
[here](https://github.com/rainlanguage/specs/blob/main/dotrain.md)
- Rainlang specs can be found
[here](https://github.com/rainlanguage/specs/blob/main/rainlang.md)
- Dotrain has been implemented for vscode and codemirror, see
[rainlang-vscode](https://github.com/rainlanguage/rainlang-vscode) and
[rainlang-codemirror](https://github.com/rainlanguage/rainlang-codemirror)
repositories for more details.
- Dotrain vscode extension can be found
[here](https://marketplace.visualstudio.com/items?itemName=rainprotocol.rainlang-vscode).
- [Dotrain specs](https://github.com/rainlanguage/specs/blob/main/dotrain.md)
- [Rainlang specs](https://github.com/rainlanguage/specs/blob/main/rainlang.md)
- Dotrain has been implemented for vscode and codemirror, see
[rainlang-vscode](https://github.com/rainlanguage/rainlang-vscode) and
[rainlang-codemirror](https://github.com/rainlanguage/rainlang-codemirror)
repositories for more details.
- [Dotrain vscode extension](https://marketplace.visualstudio.com/items?itemName=rainprotocol.rainlang-vscode)
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 14-14: Link text should be descriptive

(MD059, descriptive-link-text)


[warning] 16-16: Link text should be descriptive

(MD059, descriptive-link-text)


[warning] 22-22: Link text should be descriptive

(MD059, descriptive-link-text)

🤖 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 `@README.md` around lines 13 - 22, The README.md file uses bare "[here]" as
link text in three locations (lines 14, 16, and 22), which violates
accessibility best practices. Replace each instance with descriptive link text
that clearly conveys the destination: for the Dotrain specs link on line 14, use
text like "Dotrain specifications"; for the Rainlang specs link on line 16, use
"Rainlang specifications"; and for the vscode extension marketplace link on line
22, use descriptive text like "Dotrain vscode extension on Visual Studio
Marketplace" or similar that indicates the actual resource being linked.

thedavidmeister and others added 2 commits June 16, 2026 01:10
The four red checks (rs-static, rs-test ubuntu+macos, js-bindings) all
failed at the GitHub Actions "Prepare all required actions" step while
downloading rainlanguage/rainix@main: the action's root LICENSE was a
symlink the action-download step could not resolve. rainix main now
ships LICENSE as a regular file, so re-resolving the action against
current main unblocks every job. No dotrain source change is required;
fmt, clippy, cargo test, and the js-bindings build/test/docs all pass
locally against the bumped flake.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drops manual-release.yaml (manual workflow_dispatch) for package-release.yaml calling the shared rainlanguage/rainix rainix-autopublish reusable — auto-publishes the dotrain + dotrain-lsp crates to crates.io and the @rainlanguage/dotrain npm package on merge to main, version-bumped in lockstep, like every other rain repo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@thedavidmeister

Copy link
Copy Markdown
Contributor Author

Reworked the release to autopublish like the rest of the org: dropped manual-release.yaml (manual workflow_dispatch) and added package-release.yaml calling the shared rainix-autopublish reusable — it auto-publishes the dotrain + dotrain-lsp crates and the @rainlanguage/dotrain npm package on merge to main, version-bumped in lockstep (same merge-driven model as every other rain repo).

One thing to confirm before merge: crates.io currently shows dotrain/dotrain-lsp as not yet published, so the first merge to main will publish them for the first time — confirm that is intended (vs npm-only).

@thedavidmeister

Copy link
Copy Markdown
Contributor Author

Confirmed by maintainer: the dotrain + dotrain-lsp crates should publish to crates.io — so the crates: input stays. The first merge to main will claim + publish them (the repo already has CARGO_REGISTRY_TOKEN, carried over via secrets: inherit).

@thedavidmeister

Copy link
Copy Markdown
Contributor Author

Correction to my note above: dotrain and dotrain-lsp are in fact already published on crates.io (both at 6.0.1-alpha.24, in lockstep with the npm package) — my earlier 'not yet published' was a bad lookup. So this is a normal version-bump-and-republish on merge, not a first publish; no name-claim risk. Nothing to change in the PR.

Co-Authored-By: Claude <noreply@anthropic.com>

@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: 1

Caution

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

⚠️ Outside diff range comments (1)
.github/workflows/package-release.yaml (1)

1-17: ⚠️ Potential issue | 🔴 Critical

Review comment contains critical inaccuracies about lockstep versioning and wasm build handling.

The reusable workflow has significant issues that contradict the review's assumptions:

  1. Version bumping is NOT lockstep: The npm package always bumps as patch (hardcoded at line 241: npm version patch --no-git-tag-version), while the Rust crates respect inputs.level. If a major or minor version bump is needed, the npm package will bump patch instead, breaking synchronization.

  2. Wasm bindings are not built before publish: The workflow has no build step before npm pack. The prepublish hook in package.json (line 34) is never invoked. Cargo test doesn't build wasm either—it only runs tests. The npm package will pack whatever artifacts exist in the working directory, risking stale or missing wasm bindings.

  3. Secrets are properly scoped: Each secret is used only where needed (e.g., CARGO_REGISTRY_TOKEN in crates publish, NPM_PUBLISH_PRIVATE_TOKEN in npm publish).

The workflow parameters do match expectations, but the implementation does not safely handle the dual-artifact release model claimed in the workflow description.

🤖 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 @.github/workflows/package-release.yaml around lines 1 - 17, The workflow
currently passes the crates and npm-package to the reusable rainix-autopublish
workflow, but does not account for version bumping misalignment or missing wasm
build steps. To fix this, you need to: first, ensure that the version level
input parameter is passed through the with section to the reusable workflow so
that npm package version bumping respects the same semantic versioning level
(major, minor, patch) as the Rust crates instead of always bumping patch, and
second, add a build step in the workflow (either before invoking the reusable
workflow or as an input parameter to it) that explicitly builds the wasm
bindings before npm pack is executed, ensuring the prepublish hook or equivalent
build process generates the necessary artifacts rather than relying on stale or
missing bindings in the working directory.
🤖 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 @.github/workflows/package-release.yaml:
- Line 12: The reusable workflow reference in the rainix-autopublish.yaml uses
statement is pinned to `@main` instead of a specific commit hash, which allows
upstream changes to execute without explicit review. Replace the `@main` reference
in the uses statement with the specific commit hash
f6bca081825f0fed57a8885e58feb4296307da20 to ensure the workflow definition
remains immutable and prevent unreviewed behavioral changes from the
rainlanguage/rainix repository.

---

Outside diff comments:
In @.github/workflows/package-release.yaml:
- Around line 1-17: The workflow currently passes the crates and npm-package to
the reusable rainix-autopublish workflow, but does not account for version
bumping misalignment or missing wasm build steps. To fix this, you need to:
first, ensure that the version level input parameter is passed through the with
section to the reusable workflow so that npm package version bumping respects
the same semantic versioning level (major, minor, patch) as the Rust crates
instead of always bumping patch, and second, add a build step in the workflow
(either before invoking the reusable workflow or as an input parameter to it)
that explicitly builds the wasm bindings before npm pack is executed, ensuring
the prepublish hook or equivalent build process generates the necessary
artifacts rather than relying on stale or missing bindings in the working
directory.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: b927471d-0f4d-417e-ae44-50b494d564a7

📥 Commits

Reviewing files that changed from the base of the PR and between d79cab0 and 809dc5a.

📒 Files selected for processing (2)
  • .github/workflows/manual-release.yaml
  • .github/workflows/package-release.yaml
💤 Files with no reviewable changes (1)
  • .github/workflows/manual-release.yaml

# npm package on every merge to main, version-bumped in lockstep by the shared
# rainix-autopublish reusable — the same merge-driven model every other rain repo
# uses. Replaces the old manual `workflow_dispatch` release.
uses: rainlanguage/rainix/.github/workflows/rainix-autopublish.yaml@main

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find the latest commit hash for the rainix repository's main branch
git ls-remote https://github.com/rainlanguage/rainix.git main | awk '{print $1}'

Repository: rainlanguage/dotrain

Length of output: 105


Pin the reusable workflow to a specific commit hash instead of using @main.

Line 12 uses @main, which allows upstream changes to the reusable workflow in rainlanguage/rainix to alter publish behavior without explicit review. Pin to a specific commit hash:

uses: rainlanguage/rainix/.github/workflows/rainix-autopublish.yaml@f6bca081825f0fed57a8885e58feb4296307da20

This ensures the workflow definition is immutable and prevents unreviewed behavioral changes.

🧰 Tools
🪛 zizmor (1.25.2)

[error] 12-12: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[warning] 12-12: secrets unconditionally inherited by called workflow (secrets-inherit): this reusable workflow

(secrets-inherit)

🤖 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 @.github/workflows/package-release.yaml at line 12, The reusable workflow
reference in the rainix-autopublish.yaml uses statement is pinned to `@main`
instead of a specific commit hash, which allows upstream changes to execute
without explicit review. Replace the `@main` reference in the uses statement with
the specific commit hash f6bca081825f0fed57a8885e58feb4296307da20 to ensure the
workflow definition remains immutable and prevent unreviewed behavioral changes
from the rainlanguage/rainix repository.

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