Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
35b5879
Commit subgraph/abis + subgraph/generated; use rainix-subgraph-test r…
thedavidmeister May 30, 2026
c0b0c7d
Drop prep-base.sh; callers use pointers.sh
thedavidmeister May 30, 2026
a67348d
Strip subgraph ABIs to .abi; cover .prettierignore in REUSE
thedavidmeister May 30, 2026
b5b0156
Bump rainix to c465734 (pulls in pkgs.sqlite + subgraph-test npm ci)
thedavidmeister May 30, 2026
beabddf
Split rainix.yaml into per-task slim-shell workflows
thedavidmeister May 30, 2026
cda8492
Commit crates/bindings/abis + rename hook to script/build.sh
thedavidmeister May 30, 2026
beb0f40
Bump rainix to 81c6e4e (build.sh hook rename)
thedavidmeister May 30, 2026
f3d0165
Retrigger CI (transient cachix 403 on copy-artifacts post-step)
thedavidmeister May 30, 2026
e93d9a5
Merge #2606 (subgraph + bindings committed artifacts) into split branch
thedavidmeister May 30, 2026
b1708ec
Add Swatinem/rust-cache@v2 to direct-cargo workflows
thedavidmeister May 30, 2026
7144f02
test_fixtures: commit ABIs + vendor IMulticall3.sol
thedavidmeister May 30, 2026
10deefb
Add MIT and Apache-2.0 license texts for vendored IMulticall3.sol
thedavidmeister May 30, 2026
662ff19
Apply pre-commit hooks (denofmt/yamlfmt/shellcheck)
thedavidmeister May 30, 2026
080ea7d
test-js-bindings: invoke flake task in default devshell
thedavidmeister May 30, 2026
4db76d3
test-js-bindings: use slim #wasm-shell with workspace-root npm install
thedavidmeister May 30, 2026
e0e1b0b
build.sh: pass pipeline via bash -c, not heredoc
thedavidmeister May 30, 2026
fc28f27
Slim shells via flake.lock + drop non-deterministic sourceMap
thedavidmeister May 30, 2026
f3dcc8c
Remove prep-all.sh + pointers.sh; consolidate CI on cachix
thedavidmeister May 30, 2026
dd431c3
Delete prep-webapp.sh; inline at the 4 callers
thedavidmeister May 30, 2026
f53e16c
Drop forge from webapp/ui-components/vercel workflows
thedavidmeister May 30, 2026
1109697
Switch webapp/ui-components/vercel workflows to slim #wasm-shell
thedavidmeister May 30, 2026
2853b55
AGENTS.md: document CI & workflow conventions
thedavidmeister May 30, 2026
4e1c563
Slim shells across all remaining workflows; drop redundant forge/rm
thedavidmeister May 30, 2026
2cee7e2
npm cache: per-workflow key to avoid parallel-save collision
thedavidmeister May 30, 2026
c4c2189
Add cachix-action to 6 nix-using workflows; per-workflow rust-cache key
thedavidmeister May 30, 2026
6e725e2
copilot-setup-steps: drop pull_request trigger
thedavidmeister May 30, 2026
8f94986
Retrigger CI (transient nix install fail on rs-test macos)
thedavidmeister May 30, 2026
83354e4
copilot-setup-steps: trigger on pull_request only
thedavidmeister May 30, 2026
fa519a8
copilot-setup-steps: workflow_dispatch only
thedavidmeister May 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# shellcheck shell=bash
if ! has nix_direnv_version || ! nix_direnv_version 3.0.6; then
URL=https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.6/direnvrc
HASH=sha256-RYcUJaRMf8oF5LznDrlCXbkOQrywm0HDv1VjYGaJGdM=
Expand Down
53 changes: 35 additions & 18 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
> NOTE: Before using this guide, read the repository root `AGENTS.md` for authoritative agent instructions.
> NOTE: Before using this guide, read the repository root `AGENTS.md` for
> authoritative agent instructions.

# Raindex – Agent Guide (Concise)

Always run commands via Nix: `nix develop -c <command>`. Never cancel long-running tasks (45–90 min builds, 30+ min tests).
Always run commands via Nix: `nix develop -c <command>`. Never cancel
long-running tasks (45–90 min builds, 30+ min tests).

## 1. Dependency readiness (quick check)

```bash
nix develop -c cargo build
nix develop -c cargo build --target wasm32-unknown-unknown --lib -r --workspace \
Expand All @@ -17,34 +20,44 @@ nix develop -c npm run build:ui
If any step fails due to earlier lint/test issues, use the fallback below.

## 2. Development loop

- Edit code
- Rebuild dependencies you touched:
- Rust used by `@rainlanguage/raindex` → `nix develop -c npm run build:raindex`
- `@rainlanguage/ui-components` → `nix develop -c npm run build -w @rainlanguage/ui-components`
- Rust used by `@rainlanguage/raindex` →
`nix develop -c npm run build:raindex`
- `@rainlanguage/ui-components` →
`nix develop -c npm run build -w @rainlanguage/ui-components`
- Run targeted tests and lints for changed areas

## Reference: tests and lints by area

| Area | Build (if needed) | Lint/Check | Tests |
|------|--------------------|------------|-------|
| Rust crates (`crates/*`) | `nix develop -c cargo build` | `nix develop -c cargo clippy --workspace --all-targets --all-features -D warnings` | `nix develop -c cargo test --workspace` or `--package <crate>` |
| Raindex TS (`packages/raindex`) | `nix develop -c npm run build:raindex` | `nix develop -c npm run check -w @rainlanguage/raindex` | `nix develop -c npm run test -w @rainlanguage/raindex` |
| UI components (`packages/ui-components`) | `nix develop -c npm run build -w @rainlanguage/ui-components` | `nix develop -c npm run svelte-lint-format-check -w @rainlanguage/ui-components` | `nix develop -c npm run test -w @rainlanguage/ui-components` |
| Webapp (`packages/webapp`) | `nix develop -c npm run build -w @rainlanguage/webapp` | `nix develop -c npm run svelte-lint-format-check -w @rainlanguage/webapp` | `nix develop -c npm run test -w @rainlanguage/webapp` |
| Solidity contracts | `nix develop -c forge build` | — | `nix develop -c forge test` |
| Area | Build (if needed) | Lint/Check | Tests |
| ---------------------------------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------- | -------------------------------------------------------------- |
| Rust crates (`crates/*`) | `nix develop -c cargo build` | `nix develop -c cargo clippy --workspace --all-targets --all-features -D warnings` | `nix develop -c cargo test --workspace` or `--package <crate>` |
| Raindex TS (`packages/raindex`) | `nix develop -c npm run build:raindex` | `nix develop -c npm run check -w @rainlanguage/raindex` | `nix develop -c npm run test -w @rainlanguage/raindex` |
| UI components (`packages/ui-components`) | `nix develop -c npm run build -w @rainlanguage/ui-components` | `nix develop -c npm run svelte-lint-format-check -w @rainlanguage/ui-components` | `nix develop -c npm run test -w @rainlanguage/ui-components` |
| Webapp (`packages/webapp`) | `nix develop -c npm run build -w @rainlanguage/webapp` | `nix develop -c npm run svelte-lint-format-check -w @rainlanguage/webapp` | `nix develop -c npm run test -w @rainlanguage/webapp` |
| Solidity contracts | `nix develop -c forge build` | — | `nix develop -c forge test` |

## Frontend verification (required when frontend changes)

- If you modify frontend code or functionality affecting the frontend, you MUST provide a screenshot of the built webapp reflecting your change.
- If you modify frontend code or functionality affecting the frontend, you MUST
provide a screenshot of the built webapp reflecting your change.
- Build and preview:

```bash
nix develop -c npm run build -w @rainlanguage/webapp
nix develop -c npm run preview -w @rainlanguage/webapp
```
- If you are unable to build the webapp, you MUST provide the concrete reasons and errors. Workarounds are not acceptable.

- If you are unable to build the webapp, you MUST provide the concrete reasons
and errors. Workarounds are not acceptable.

## 3. End-of-session gate (comprehensive)
Partial commits are OK during the session. Before your final commit of the session, fully mirror CI:

Partial commits are OK during the session. Before your final commit of the
session, fully mirror CI:

```bash
./prep-all.sh
nix develop -c npm run lint-format-check:all
Expand All @@ -56,15 +69,20 @@ nix develop -c forge test
```

## 4. Push gate (quick recheck)

Do a short verification right before pushing:

```bash
nix develop -c npm run lint-format-check:all
nix develop -c npm run test
nix develop -c cargo test --workspace
```

## Fallback if end-of-session `./prep-all.sh` fails early
If the end-of-session gate fails during `./prep-all.sh`, run these steps sequentially so dependencies still build:

If the end-of-session gate fails during `./prep-all.sh`, run these steps
sequentially so dependencies still build:

```bash
nix develop -c forge install
nix develop -c bash -c '(cd lib/rain.interpreter && rainix-sol-prelude && rainix-rs-prelude && rainlang-prelude)'
Expand All @@ -77,6 +95,5 @@ nix develop -c npm run build -w @rainlanguage/ui-components
nix develop -c npm run build -w @rainlanguage/webapp
```

Goal: all CI checks in `.github/workflows` pass. Be patient with long builds/tests and never commit with failing lint/tests.


Goal: all CI checks in `.github/workflows` pass. Be patient with long
builds/tests and never commit with failing lint/tests.
44 changes: 32 additions & 12 deletions .github/workflows/copilot-setup-steps.yml
Original file line number Diff line number Diff line change
@@ -1,42 +1,62 @@
name: Copilot Agent Setup
on:
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.yml
pull_request:
paths:
- .github/workflows/copilot-setup-steps.yml
jobs:
copilot-setup-steps:
permissions:
id-token: write
contents: read
runs-on: ubuntu-latest
env:
PUBLIC_WALLETCONNECT_PROJECT_ID: ${{ secrets.WALLETCONNECT_PROJECT_ID || 'test' }}
COMMIT_SHA: ${{ github.sha }}
steps:
- uses: actions/checkout@v4
- uses: nixbuild/nix-quick-install-action@v30
with:
nix_conf: |
keep-env-derivations = true
keep-outputs = true
- uses: cachix/cachix-action@v15
continue-on-error: true
with:
name: rainlanguage
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
useDaemon: false
- name: Restore and save Nix store
uses: nix-community/cache-nix-action@v6
uses: nix-community/cache-nix-action@v7
with:
primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-
gc-max-store-size-linux: 1G
- uses: Swatinem/rust-cache@v2
with:
prefix-key: rust-${{ github.workflow }}
- name: Cache npm
uses: actions/cache@v4
Comment on lines +20 to +36

Copy link
Copy Markdown
Contributor

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the relevant section from the target workflow
target=".github/workflows/copilot-setup-steps.yml"
if [ -f "$target" ]; then
  echo "=== $target (lines 1-120) ==="
  nl -ba "$target" | sed -n '1,120p'
else
  echo "Missing file: $target" >&2
fi

# Find other workflows' uses patterns (pinning vs version tags)
echo
echo "=== Scan other workflows for uses:@<sha> vs uses:`@v`* ==="
# List all workflow files
wf_files=$(git ls-files ".github/workflows/**/*.{yml,yaml}" 2>/dev/null || true)
echo "Workflows found: $(echo "$wf_files" | wc -l)"

# Count uses lines with @<40-hex> and with `@v`
echo "Counts across workflows:"
printf "%s\n" "$wf_files" | while read -r f; do
  [ -n "$f" ] || continue
  # sha-like (at least 40 hex chars)
  sha_cnt=$(rg -n --no-heading "uses:\s+[^ ]+@[0-9a-f]{40,}" "$f" -S --count || true)
  # common version tags
  ver_cnt=$(rg -n --no-heading "uses:\s+[^ ]+@v[0-9]+(\.[0-9]+)*" "$f" -S --count || true)
  # actions without pin (heuristic: uses: ...@v or uses: ...@* but not sha)
  unpinned_cnt=$(rg -n --no-heading "uses:\s+[^ ]+@(?![0-9a-f]{40,})[^ ]+" "$f" -S --count || true)
  printf "%-70s sha=%s ver=%s unpinned=%s\n" "$f" "${sha_cnt:-0}" "${ver_cnt:-0}" "${unpinned_cnt:-0}"
done

Repository: rainlanguage/raindex

Length of output: 189


🏁 Script executed:

#!/bin/bash
set -euo pipefail

target=".github/workflows/copilot-setup-steps.yml"
if [ -f "$target" ]; then
  echo "=== $target (first 160 lines) ==="
  awk '{printf "%4d\t%s\n", NR, $0}' "$target" | sed -n '1,160p'
else
  echo "Missing file: $target" >&2
  exit 1
fi

echo
echo "=== Scan other workflows for uses:@<sha> vs uses:`@v`* ==="
wf_files=$(git ls-files ".github/workflows/**/*.{yml,yaml}" 2>/dev/null || true)
echo "Workflows found: $(echo "$wf_files" | wc -l)"

printf "%-70s %12s %12s %12s\n" "workflow" "sha_pins" "version_uses" "unpinned"
printf "%-70s %12s %12s %12s\n" "--------" "---------" "-------------" "--------"

while read -r f; do
  [ -n "$f" ] || continue

  sha_cnt=$(rg -n --no-heading "uses:\s+[^ ]+@[0-9a-f]{40,}" "$f" -S --count || true)
  ver_cnt=$(rg -n --no-heading "uses:\s+[^ ]+@v[0-9]+(\.[0-9]+)*" "$f" -S --count || true)

  # "unpinned" heuristic: uses something that's not a full SHA (>=40 hex), including `@v`* tags.
  unpinned_cnt=$(rg -n --no-heading "uses:\s+[^ ]+@(?:(?![0-9a-f]{40,})[^ ]+)" "$f" -S --count || true)

  printf "%-70s %12s %12s %12s\n" "$f" "${sha_cnt:-0}" "${ver_cnt:-0}" "${unpinned_cnt:-0}"
done <<< "$wf_files"

Repository: rainlanguage/raindex

Length of output: 3353


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== List .github/workflows tree ==="
ls -R .github/workflows || true

echo
echo "=== List workflow files tracked by git ==="
git ls-files ".github/workflows/**/*.{yml,yaml}" || true

echo
echo "=== Scan all workflow files (uses pinning patterns) ==="
wf_files=$(git ls-files ".github/workflows/**/*.{yml,yaml}" 2>/dev/null || true)
echo "Workflows found: $(echo "$wf_files" | wc -l)"

printf "%-70s %12s %12s %12s\n" "workflow" "sha_pins" "version_uses" "unpinned"
printf "%-70s %12s %12s %12s\n" "--------" "---------" "-------------" "--------"

while read -r f; do
  [ -n "$f" ] || continue
  sha_cnt=$(rg -n --no-heading "uses:\s+[^ ]+@[0-9a-f]{40,}" "$f" -S --count || true)
  ver_cnt=$(rg -n --no-heading "uses:\s+[^ ]+@v[0-9]+(\.[0-9]+)*" "$f" -S --count || true)
  unpinned_cnt=$(rg -n --no-heading "uses:\s+[^ ]+@(?:(?![0-9a-f]{40,})[^ ]+)" "$f" -S --count || true)
  printf "%-70s %12s %12s %12s\n" "$f" "${sha_cnt:-0}" "${ver_cnt:-0}" "${unpinned_cnt:-0}"
done <<< "$wf_files"

Repository: rainlanguage/raindex

Length of output: 883


🏁 Script executed:

#!/bin/bash
set -euo pipefail

shopt -s nullglob
files=(.github/workflows/*.{yml,yaml} .github/workflows/*/*.yml .github/workflows/*/*.yaml)
# filter existing
existing=()
for f in "${files[@]}"; do
  [ -f "$f" ] && existing+=("$f")
done

echo "Found workflow files:"
printf ' - %s\n' "${existing[@]}"

echo
echo "=== Any uses pinned to SHAs (40+ hex) in workflows? ==="
rg -n --no-heading "uses:\s+[^ ]+@[0-9a-f]{40,}" "${existing[@]}" -S || true

echo
echo "=== Count uses by pin type ==="
for f in "${existing[@]}"; do
  sha_cnt=$(rg -n --no-heading "uses:\s+[^ ]+@[0-9a-f]{40,}" "$f" -S --count || true)
  ver_cnt=$(rg -n --no-heading "uses:\s+[^ ]+@v[0-9]+(\.[0-9]+)*" "$f" -S --count || true)
  branch_cnt=$(rg -n --no-heading "uses:\s+[^ ]+@main|uses:\s+[^ ]+@master|uses:\s+[^ ]+@refs/heads/" "$f" -S --count || true)
  other_cnt=$(rg -n --no-heading "uses:\s+[^ ]+@(?:(?![0-9a-f]{40,}).[^ \n]+)" "$f" -S --count || true)
  printf "%-35s sha=%-3s ver=%-3s branch=%-3s other=%s\n" "$f" "$sha_cnt" "$ver_cnt" "$branch_cnt" "$other_cnt"
done

echo
echo "=== Unique unpinned uses in copilot-setup-steps.yml ==="
rg -n --no-heading "uses:\s+[^ ]+@(?:(?![0-9a-f]{40,}).[^ \n]+)" ".github/workflows/copilot-setup-steps.yml" -S || true

Repository: rainlanguage/raindex

Length of output: 8452


Pin newly added workflow actions to commit SHAs

In .github/workflows/copilot-setup-steps.yml (lines 20-36), these actions are referenced only via mutable version tags (cachix/cachix-action@v15, nix-community/cache-nix-action@v7, Swatinem/rust-cache@v2, actions/cache@v4). Pin each uses: to an immutable full commit SHA (...@<40+hex>) instead.

🧰 Tools
🪛 zizmor (1.25.2)

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

(unpinned-uses)


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

(unpinned-uses)


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

(unpinned-uses)


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

(unpinned-uses)

🤖 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/copilot-setup-steps.yml around lines 20 - 36, The workflow
uses mutable tags for several actions (cachix/cachix-action@v15,
nix-community/cache-nix-action@v7, Swatinem/rust-cache@v2, actions/cache@v4);
replace each `uses:` reference with the corresponding immutable commit SHA (e.g.
`owner/repo@<full-commit-sha>`) to pin versions, keeping existing `with:` inputs
and step names unchanged; fetch the latest trusted commit SHAs from each
action's GitHub repo/releases, update the four `uses:` lines accordingly, and
commit the updated workflow.

with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ github.workflow }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: npm-${{ runner.os }}-
- name: Prepare environment files
run: |
set -euxo pipefail
cp -f .env.example .env
cp -f packages/webapp/.env.example packages/webapp/.env
cp -f .env.example crates/common/.env
- name: Prepare repository dependencies
run: ./prep-all.sh
env:
PUBLIC_WALLETCONNECT_PROJECT_ID: ${{ secrets.WALLETCONNECT_PROJECT_ID || 'test' }}
COMMIT_SHA: ${{ github.sha }}
# Inlined bootstrap (formerly ./prep-all.sh). All committed ABIs +
# vendored IMulticall3.sol mean cargo doesn't need forge build /
# soldeer install — forge is still on PATH in .#sol-shell if copilot
# needs it later.
- run: |
nix develop .#wasm-shell -c bash -c '
set -euxo pipefail
npm install --no-check
(cd packages/ui-components && npm i && npm run lint)
npm run build -w @rainlanguage/raindex
npm run build -w @rainlanguage/ui-components
npm run build -w @rainlanguage/webapp
'
Comment on lines +51 to +59

Copy link
Copy Markdown
Contributor

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

Drop the package-local npm i here.

After the root npm install --no-check, doing another install inside packages/ui-components reintroduces the exact workspace-resolution problem this shell wrapper is avoiding. Run the lint script from the root workspace instead.

Suggested change
           nix develop .#wasm-shell -c bash -c '
             set -euxo pipefail
             npm install --no-check
-            (cd packages/ui-components && npm i && npm run lint)
+            npm run lint -w `@rainlanguage/ui-components`
             npm run build -w `@rainlanguage/raindex`
             npm run build -w `@rainlanguage/ui-components`
             npm run build -w `@rainlanguage/webapp`
           '
Based on learnings `npm install --no-check` must run from the workspace root (not `packages/`) for npm workspaces resolution; slim shells require explicit execution as the first command inside `bash -c '...'`.
📝 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
- run: |
nix develop .#wasm-shell -c bash -c '
set -euxo pipefail
npm install --no-check
(cd packages/ui-components && npm i && npm run lint)
npm run build -w @rainlanguage/raindex
npm run build -w @rainlanguage/ui-components
npm run build -w @rainlanguage/webapp
'
- run: |
nix develop .#wasm-shell -c bash -c '
set -euxo pipefail
npm install --no-check
npm run lint -w `@rainlanguage/ui-components`
npm run build -w `@rainlanguage/raindex`
npm run build -w `@rainlanguage/ui-components`
npm run build -w `@rainlanguage/webapp`
'
🤖 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/copilot-setup-steps.yml around lines 51 - 59, Remove the
package-local install and run lint from the workspace root: delete the subshell
"(cd packages/ui-components && npm i && npm run lint)" and instead, after
running "npm install --no-check" at the root inside the bash -c block, invoke
the workspace lint from the root (e.g., "npm run lint -w
`@rainlanguage/ui-components`" or the root "npm run lint" that covers that
package); ensure "npm install --no-check" remains the first command inside the
bash -c to preserve proper npm workspace resolution.

# forwards status to telegram chat if this ci fails or gets canceled, only runs for default branch
- name: Forward CI Status
if: always()
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/deploy-subgraph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ jobs:
nix_conf: |
keep-env-derivations = true
keep-outputs = true
- uses: cachix/cachix-action@v15
continue-on-error: true
with:
name: rainlanguage
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
useDaemon: false
Comment on lines +22 to +27

Copy link
Copy Markdown
Contributor

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

ls -la .github/workflows || true
sed -n '1,140p' .github/workflows/deploy-subgraph.yaml | nl -ba | sed -n '1,160p'
echo "---- other workflows (action pinning conventions) ----"
fd -t f -g '*.yml' .github/workflows -x echo {} >/dev/null 2>&1 || true
# List some uses lines containing cachix/cachix-action and also any unpinned uses occurrences
rg -n "uses:\s*[^@]+@v\d+(\.\d+)*\s*$" .github/workflows --glob '*.yml' --glob '*.yaml' || true
rg -n "uses:\s*cachix/cachix-action@" .github/workflows --glob '*.yml' --glob '*.yaml' || true
# Collect a few uses lines with SHA pinning patterns
rg -n "uses:\s*[^@]+@[0-9a-f]{7,40}\s*$" .github/workflows --glob '*.yml' --glob '*.yaml' | head -n 50 || true

Repository: rainlanguage/raindex

Length of output: 1713


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the relevant workflow section around lines ~10-40 with line numbers
if [ -f ".github/workflows/deploy-subgraph.yaml" ]; then
  sed -n '1,160p' .github/workflows/deploy-subgraph.yaml | nl -ba | sed -n '1,200p'
fi

echo "---- Find uses: lines in deploy-subgraph.yaml ----"
rg -n "uses:" .github/workflows/deploy-subgraph.yaml || true

echo "---- Repo-wide workflow conventions: find unpinned uses refs ----"
# Heuristic: floating tags like `@v1`, `@v2`, `@v15` etc (not SHA-like)
rg -n --glob '*.yml' --glob '*.yaml' "uses:\s*[^@]+@v[0-9]+(\.[0-9]+)*\s*$" .github/workflows || true

echo "---- Repo-wide: find cachix/cachix-action occurrences ----"
rg -n --glob '*.yml' --glob '*.yaml' "uses:\s*cachix/cachix-action@" .github/workflows || true

echo "---- Repo-wide: find uses pinned to commit SHA ----"
rg -n --glob '*.yml' --glob '*.yaml' "uses:\s*[^@]+@[0-9a-f]{7,40}\s*$" .github/workflows | head -n 80 || true

Repository: rainlanguage/raindex

Length of output: 107


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the workflow section with line numbers
if [ -f ".github/workflows/deploy-subgraph.yaml" ]; then
  sed -n '1,160p' .github/workflows/deploy-subgraph.yaml | nl -ba | sed -n '1,220p'
fi

echo "---- Find uses: lines in deploy-subgraph.yaml ----"
rg -n "uses:" .github/workflows/deploy-subgraph.yaml || true

echo "---- Repo-wide workflow conventions: unpinned uses refs (heuristic) ----"
rg -n --glob '*.yml' --glob '*.yaml' "uses:\s*[^@]+@v[0-9]+(\.[0-9]+)*\s*$" .github/workflows || true

echo "---- Repo-wide: cachix/cachix-action occurrences ----"
rg -n --glob '*.yml' --glob '*.yaml' "uses:\s*cachix/cachix-action@" .github/workflows || true

echo "---- Repo-wide: uses pinned to commit SHA (heuristic) ----"
rg -n --glob '*.yml' --glob '*.yaml' "uses:\s*[^@]+@[0-9a-f]{7,40}\s*$" .github/workflows | head -n 80 || true

Repository: rainlanguage/raindex

Length of output: 107


🏁 Script executed:

#!/bin/bash
set -euo pipefail

wf=".github/workflows/deploy-subgraph.yaml"
if [ -f "$wf" ]; then
  echo "---- $wf (lines 1-120) ----"
  sed -n '1,120p' "$wf" | awk '{printf "%4d\t%s\n", NR, $0}'
fi

echo "---- uses: lines in deploy-subgraph.yaml ----"
rg -n "uses:" "$wf" || true

echo "---- cachix/cachix-action occurrences ----"
rg -n --glob '*.yml' --glob '*.yaml' "uses:\s*cachix/cachix-action@" .github/workflows || true

echo "---- repo-wide unpinned uses refs (heuristic: `@v`*) ----"
rg -n --glob '*.yml' --glob '*.yaml' "uses:\s*[^@]+@v[0-9]+(\.[0-9]+)*\s*$" .github/workflows || true

echo "---- repo-wide uses pinned to commit SHA (heuristic) ----"
rg -n --glob '*.yml' --glob '*.yaml' "uses:\s*[^@]+@[0-9a-f]{7,40}\s*$" .github/workflows | head -n 80 || true

Repository: rainlanguage/raindex

Length of output: 10509


Pin cachix/cachix-action to a commit SHA (avoid floating tags).

.github/workflows/deploy-subgraph.yaml uses cachix/cachix-action@v15; pin it to the exact commit SHA to prevent upstream tag retargeting in this privileged deploy workflow.

🧰 Tools
🪛 zizmor (1.25.2)

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

(unpinned-uses)

🤖 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/deploy-subgraph.yaml around lines 22 - 27, Locate the
GitHub Actions step that currently uses "cachix/cachix-action@v15" in the deploy
workflow and replace the floating tag with the upstream action's exact commit
SHA (e.g., "cachix/cachix-action@<full-commit-sha>"); keep the existing inputs
(name, authToken, useDaemon, continue-on-error) unchanged, and ensure you use
the full-length commit SHA from the cachix/cachix-action repository to prevent
tag retargeting.

- name: Restore and save Nix store
uses: nix-community/cache-nix-action@v6
with:
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/manual-rs-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ jobs:
nix_conf: |
keep-env-derivations = true
keep-outputs = true
- uses: cachix/cachix-action@v15
continue-on-error: true
with:
name: rainlanguage
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
useDaemon: false
Comment on lines +16 to +21

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Show the full workflow for manual-rs-release.yml (small file likely)
echo "=== manual-rs-release.yml ==="
if [ -f ".github/workflows/manual-rs-release.yml" ]; then
  sed -n '1,220p' .github/workflows/manual-rs-release.yml | cat -n
else
  echo "Missing: .github/workflows/manual-rs-release.yml"
fi

# 2) Find other workflows that mention Cachix and/or Rust caching conventions
echo
echo "=== Workflows using cachix/cachix-action ==="
rg -n "cachix/cachix-action@" .github/workflows --hidden || true

echo
echo "=== Workflows using Rust cache actions (common patterns) ==="
rg -n "rust-cache|Swatinem/rust-cache|actions/cache.*cargo|cache.*cargo|cache.*rust" .github/workflows --hidden || true

echo
echo "=== List all workflows files (for convention comparison) ==="
ls -1 .github/workflows || true

Repository: rainlanguage/raindex

Length of output: 4487


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo "=== Manual rs release: rust cache references ==="
rg -n "rust-cache|Swatinem/rust-cache|actions/cache|cache.*cargo|cache.*rust" .github/workflows/manual-rs-release.yml || true

Repository: rainlanguage/raindex

Length of output: 113


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo "=== Manual rs release: rust cache references ==="
rg -n "rust-cache|Swatinem/rust-cache|actions/cache|cache.*cargo|cache.*rust" .github/workflows/manual-rs-release.yml || true

Repository: rainlanguage/raindex

Length of output: 113


Pin cachix/cachix-action to a commit SHA instead of @v15 in .github/workflows/manual-rs-release.yml. Floating uses: refs weaken the trust boundary on a release workflow.

🧰 Tools
🪛 zizmor (1.25.2)

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

(unpinned-uses)

🤖 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-rs-release.yml around lines 16 - 21, Replace the
floating action ref cachix/cachix-action@v15 in the workflow with a specific
commit SHA to pin the dependency; update the line that currently references
cachix/cachix-action@v15 in .github/workflows/manual-rs-release.yml to use
cachix/cachix-action@<COMMIT_SHA> (the exact commit SHA you choose), verify the
SHA points to a release/commit you trust, and keep the other keys
(continue-on-error, with.name, with.authToken, with.useDaemon) unchanged.

- name: Restore and save Nix store
uses: nix-community/cache-nix-action@v6
with:
Expand All @@ -24,7 +30,7 @@ jobs:
# before trying to save a new cache
# 1G = 1073741824
gc-max-store-size-linux: 1G
- run: nix develop --command cargo release --workspace
- run: nix develop .#rust-shell --command cargo release --workspace
# forwards status to telegram chat if this ci fails or gets canceled, only runs for default branch
- name: Forward CI Status
if: always()
Expand Down
61 changes: 44 additions & 17 deletions .github/workflows/npm-package-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,35 @@ jobs:
with:
swap-storage: false
# install nix for building WASM artifacts and running tests
- uses: DeterminateSystems/nix-installer-action@main
- uses: nixbuild/nix-quick-install-action@v30
with:
determinate: true
# cache nix store to speed up subsequent builds
- uses: DeterminateSystems/flakehub-cache-action@main
nix_conf: |
keep-env-derivations = true
keep-outputs = true
# pull rainix derivations from shared Cachix; push new ones if the
# token is set. continue-on-error so a token miss / Cachix outage
# degrades gracefully.
- uses: cachix/cachix-action@v15
continue-on-error: true
with:
name: rainlanguage
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
useDaemon: false
- name: Restore and save Nix store
uses: nix-community/cache-nix-action@v7
with:
primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-
gc-max-store-size-linux: 8G
- uses: Swatinem/rust-cache@v2
with:
prefix-key: rust-${{ github.workflow }}
- name: Cache npm
uses: actions/cache@v4
Comment on lines +40 to +64

Copy link
Copy Markdown
Contributor

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# List the workflow file
ls -la .github/workflows/npm-package-release.yml 2>/dev/null || true

# Show the relevant portion (lines with numbers) around 1-120
sed -n '1,200p' .github/workflows/npm-package-release.yml

# Collect all uses lines in this workflow
echo "---- uses lines in npm-package-release.yml ----"
rg -n "^\s*- uses:" .github/workflows/npm-package-release.yml

# Search other workflows for pinned vs `@v`* patterns
echo "---- uses lines across workflows (sample) ----"
rg -n "^\s*- uses:" .github/workflows --glob '**/*.{yml,yaml}' | head -n 50

echo "---- count uses with `@v`* vs @<sha> (heuristic) ----"
python3 - <<'PY'
import re, subprocess, os, sys, pathlib, json
from collections import Counter

workflows_dir = pathlib.Path(".github/workflows")
paths = [str(p) for p in workflows_dir.rglob("*.yml")] + [str(p) for p in workflows_dir.rglob("*.yaml")]
pattern = re.compile(r'^\s*-\s+uses:\s*([^\s]+)@(.+?)\s*(#.*)?$')
counts = Counter()
bad = []
all_entries=[]
for path in paths:
    txt = pathlib.Path(path).read_text(errors='ignore').splitlines()
    for i,line in enumerate(txt,1):
        m = re.match(r'^\s*-\s+uses:\s*(.+?)@(.+?)\s*$', line)
        if m:
            repo, ref = m.group(1), m.group(2)
            if re.fullmatch(r'[0-9a-fA-F]{7,40}', ref):
                counts['pinned_sha'] += 1
            elif re.fullmatch(r'v\d+(\.\d+)*', ref) or ref.startswith('v'):
                counts['major_semver_tag'] += 1
            else:
                counts['other_ref'] += 1
            all_entries.append((path,i,repo,ref))
for k,v in counts.items():
    print(k, v)
# Show examples of semver tags
semver_examples=[e for e in all_entries if re.fullmatch(r'v\d+(\.\d+)*', e[3]) or e[3].startswith('v')]
print("---- semver-like ref examples (up to 25) ----")
for path,i,repo,ref in semver_examples[:25]:
    print(f"{path}:{i}: {repo}@{ref}")
# Show examples of sha pins (up to 10)
sha_examples=[e for e in all_entries if re.fullmatch(r'[0-9a-fA-F]{7,40}', e[3])]
print("---- sha pin examples (up to 10) ----")
for path,i,repo,ref in sha_examples[:10]:
    print(f"{path}:{i}: {repo}@{ref}")
PY

Repository: rainlanguage/raindex

Length of output: 17292


🏁 Script executed:

#!/bin/bash
set -euo pipefail

ls -la .github/workflows/npm-package-release.yml

sed -n '1,220p' .github/workflows/npm-package-release.yml

echo "---- uses lines in npm-package-release.yml ----"
rg -n "^\s*-\s+uses:" .github/workflows/npm-package-release.yml

echo "---- count uses with `@v`* vs @<sha> across workflows (heuristic) ----"
python3 - <<'PY'
import re, pathlib
from collections import Counter

paths = list(pathlib.Path(".github/workflows").rglob("*.yml")) + list(pathlib.Path(".github/workflows").rglob("*.yaml"))
counts=Counter()
semver=[]
sha=[]
other=[]
pattern = re.compile(r'^\s*-\s+uses:\s*(.+?)@(.+?)\s*$')
for p in paths:
    lines=p.read_text(errors='ignore').splitlines()
    for i,line in enumerate(lines,1):
        m=pattern.match(line)
        if not m: 
            continue
        ref=m.group(2).strip()
        if re.fullmatch(r'[0-9a-fA-F]{7,40}', ref):
            counts['pinned_sha']+=1; sha.append((str(p),i,m.group(1),ref))
        elif ref.startswith('v') and re.fullmatch(r'v\d+(\.\d+)*', ref):
            counts['major_semver_tag']+=1; semver.append((str(p),i,m.group(1),ref))
        else:
            counts['other_ref']+=1; other.append((str(p),i,m.group(1),ref))
print(counts)
print("sha examples:")
for e in sha[:10]:
    print(e)
print("semver examples:")
for e in semver[:10]:
    print(e)
PY

Repository: rainlanguage/raindex

Length of output: 12746


Pin external uses: actions in the release job to immutable SHAs

.github/workflows/npm-package-release.yml references third-party actions via mutable major-version tags in the release/publish path (nixbuild/nix-quick-install-action@v30, cachix/cachix-action@v15, nix-community/cache-nix-action@v7, Swatinem/rust-cache@v2, actions/cache@v4); pin these uses: refs to commit SHAs to reduce supply-chain risk.

🧰 Tools
🪛 zizmor (1.25.2)

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

(unpinned-uses)


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

(unpinned-uses)


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

(unpinned-uses)


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

(unpinned-uses)


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

(unpinned-uses)


[error] 55-55: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): always restores from cache

(cache-poisoning)


[error] 60-60: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): enables caching by default

(cache-poisoning)


[error] 64-64: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): enables caching by default

(cache-poisoning)

🤖 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/npm-package-release.yml around lines 40 - 64, The workflow
currently references third-party actions with mutable tags
(nixbuild/nix-quick-install-action@v30, cachix/cachix-action@v15,
nix-community/cache-nix-action@v7, Swatinem/rust-cache@v2, actions/cache@v4);
replace each `uses:` reference with the corresponding immutable commit SHA
(e.g., nixbuild/nix-quick-install-action@<sha>, cachix/cachix-action@<sha>,
nix-community/cache-nix-action@<sha>, Swatinem/rust-cache@<sha>,
actions/cache@<sha>) by looking up the latest vetted commit on each action’s
GitHub repo and pinning that SHA so the release job uses fixed versions.

with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ github.workflow }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: npm-${{ runner.os }}-
# setup node with npm registry for OIDC-based publishing (no NPM_TOKEN needed)
- name: Setup Node.js
uses: actions/setup-node@v4
Expand Down Expand Up @@ -86,11 +110,11 @@ jobs:
exit 1
fi
echo "Repositories match"
# install dependencies and build the workspace
- run: ./prep-base.sh
# remove debug artifacts to free disk space before WASM build
- name: Remove Unused Artifacts
run: rm -rf ./target/debug
# forge install + build is no longer needed here — all sol! macros
# read committed ABIs under crates/*/abis/, and the wasm + npm builds
# below don't shell out to forge. The prior "Remove Unused Artifacts"
# / debug-dir scrubs went with forge; rust-cache + free-disk-space@v1
# handle disk budget for the remaining WASM builds.
# WASM linker can run out of memory on GitHub runners; add swap to prevent OOM
- name: Add swap space
run: |
Expand All @@ -104,20 +128,23 @@ jobs:
sudo swapon /swapfile
# build and test WASM bindings
- name: Test JS/TS Binding 1/2
run: nix develop -c rainix-wasm-test
# cleanup between test phases to prevent disk space exhaustion
- name: Remove Test Artifacts
run: |
rm -rf ./target/debug
rm -rf ./target/wasm32-unknown-unknown/debug
nix develop .#wasm-shell -c bash -c "CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER=wasm-bindgen-test-runner cargo test --target wasm32-unknown-unknown --lib -p raindex_quote -p raindex_bindings -p raindex_js_api -p raindex_common"
# run JS/TS integration tests against WASM bindings
- name: Test JS/TS Binding 2/2
run: nix develop -c test-js-bindings
run: |
nix develop .#wasm-shell -c bash -c '
set -euxo pipefail
npm install --no-check
cd packages/raindex
npm run build
npm test
'
# build and test UI components before publishing
- name: Build UI Components
run: nix develop -c npm run build -w @rainlanguage/ui-components
run: nix develop .#wasm-shell -c npm run build -w @rainlanguage/ui-components
- name: Test UI Components
run: nix develop -c npm run test -w @rainlanguage/ui-components
run: nix develop .#wasm-shell -c npm run test -w @rainlanguage/ui-components
# check for npm package blacklists pkgs across all raindex related packages
- uses: rainlanguage/github-chore/.github/actions/npm-blacklist@main
- uses: rainlanguage/github-chore/.github/actions/npm-blacklist@main
Expand Down
13 changes: 6 additions & 7 deletions .github/workflows/pr-assessment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ on:
pull_request:
types:
- closed

jobs:
assess-pr-size-on-merge:
uses: rainlanguage/github-chore/.github/workflows/pr-assessment.yml@main
with:
pr_number: ${{ github.event.pull_request.number }}
repo: ${{ github.event.repository.name }}
owner: ${{ github.repository_owner }}
merged: ${{ github.event.pull_request.merged }}
uses: rainlanguage/github-chore/.github/workflows/pr-assessment.yml@main
with:
pr_number: ${{ github.event.pull_request.number }}
repo: ${{ github.event.repository.name }}
owner: ${{ github.repository_owner }}
merged: ${{ github.event.pull_request.merged }}
Comment thread
thedavidmeister marked this conversation as resolved.
Loading
Loading