ci: add GitHub Actions CI pipeline for contract, backend, and frontend#196
ci: add GitHub Actions CI pipeline for contract, backend, and frontend#196leocagli wants to merge 1 commit into
Conversation
Closes Stellar-Ecosystem#145 No automated gatekeeping existed — a Rust syntax error or a TS type regression could be merged with zero detection. Jobs (run in parallel on every PR and push to main): contract-build: - Installs stable Rust + wasm32-unknown-unknown target - Caches ~/.cargo and contract/target for faster re-runs - cargo test for registry contract and agents contract - cargo check --target wasm32-unknown-unknown for both (catches WASM incompatibilities without a full stellar contract build) backend-test: - npm ci + vitest run (npm test) with stub env vars so config.js passes its required-variable check without real credentials frontend-check: - npm ci + tsc --noEmit (full TypeScript type-check) - next lint (ESLint via next/eslint) - next build with stub NEXT_PUBLIC_ env vars (catches broken imports, missing pages, and bundler errors before merge)
📝 WalkthroughWalkthroughA new GitHub Actions CI workflow ( ChangesCI Workflow
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)
18-18: 🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoffConsider pinning actions to commit SHAs for supply-chain security.
Actions are currently pinned to mutable tag references (
@v4,@stable). Pinning to immutable commit SHAs prevents tag-moving attacks where maintainers could update a tag to point to malicious code.Example:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2This is a common security-vs-maintenance tradeoff. SHA pinning provides stronger guarantees but requires more frequent updates.
Also applies to: 21-21, 26-26
🤖 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/ci.yml at line 18, Replace the mutable tag reference in the actions/checkout action (currently pinned to `@v4` on line 18, and also on lines 21 and 26) with an immutable commit SHA to enhance supply-chain security. Instead of using `@v4`, pin the action to a specific commit hash followed by a comment indicating the version, such as pinning to the full SHA with a version reference (e.g., `@11bd71901bbe5b1630ceea73d27597364c9af683` # v4.2.2). This prevents potential tag-moving attacks where maintainers could update a tag to point to malicious code. Update all three occurrences of the actions/checkout action to use commit SHA pinning.Source: Linters/SAST tools
🤖 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/ci.yml:
- Line 18: The actions/checkout@v4 action is missing the persist-credentials
parameter which leaves the GITHUB_TOKEN accessible to subsequent workflow steps,
creating a security vulnerability. Add persist-credentials: false as an option
to the checkout action to ensure the GITHUB_TOKEN is not retained after the
checkout step completes, preventing potential token abuse if the checked-out
code contains malicious scripts.
- Line 84: The checkout action at line 84 does not disable credential
persistence, which poses a security risk by allowing the GITHUB_TOKEN to persist
into subsequent workflow steps. Add the `persist-credentials: false` parameter
to the `actions/checkout@v4` action to ensure that the GitHub token is not
available to downstream steps, maintaining proper defense in depth for token
management.
- Line 55: The actions/checkout@v4 action is missing the persist-credentials:
false parameter, which allows the GITHUB_TOKEN to persist into subsequent
workflow steps creating a security vulnerability. Add the persist-credentials:
false configuration option to the checkout action to ensure the GITHUB_TOKEN
does not remain available in downstream steps.
- Around line 1-11: The CI workflow lacks explicit permission declarations and
relies on GitHub's default permissions which grant excessive read-write access.
Add a `permissions` block at the top level of the workflow configuration after
the `on` section and before the `concurrency` section to explicitly declare
minimal required permissions. For a CI workflow that only needs to access
repository contents, set `contents: read` to restrict access to read-only
operations on the repository, reducing the potential attack surface if the
workflow is compromised.
- Around line 25-33: The cache key in the "Cache cargo registry" step only
includes the hash of contract/Cargo.lock, but there are two Cargo.lock files in
the repository that can affect dependencies: contract/Cargo.lock and
contract/agents/Cargo.lock. Update the key field in the with section to include
both Cargo.lock files in the hashFiles function so that cache invalidation
occurs when either file changes, preventing stale cached dependencies from
contract/agents.
- Around line 57-62: The `cache-dependency-path` configuration in the Node.js
setup action references `backend/package-lock.json` and
`frontend/package-lock.json` files that do not exist in the repository, which
prevents effective npm caching. Either generate these package-lock.json files by
running `npm install` in the backend and frontend directories respectively to
create them, or remove the `cache-dependency-path` properties from both the
setup-node action in the main job (lines 57-62) and the frontend-check job (line
91) to disable dependency path caching if package-lock files are not needed for
the project.
- Around line 86-91: The setup-node action step references a non-existent
frontend/package-lock.json file in the cache-dependency-path configuration,
which prevents npm caching from working correctly. Either remove the
cache-dependency-path line entirely to allow the action to use its default
caching behavior, or generate and commit the package-lock.json file to the
frontend directory. Choose the approach that aligns with your project's
dependency management strategy.
---
Nitpick comments:
In @.github/workflows/ci.yml:
- Line 18: Replace the mutable tag reference in the actions/checkout action
(currently pinned to `@v4` on line 18, and also on lines 21 and 26) with an
immutable commit SHA to enhance supply-chain security. Instead of using `@v4`, pin
the action to a specific commit hash followed by a comment indicating the
version, such as pinning to the full SHA with a version reference (e.g.,
`@11bd71901bbe5b1630ceea73d27597364c9af683` # v4.2.2). This prevents potential
tag-moving attacks where maintainers could update a tag to point to malicious
code. Update all three occurrences of the actions/checkout action to use commit
SHA pinning.
🪄 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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: ee575087-19b5-4a71-8586-7391e0a3c840
📒 Files selected for processing (1)
.github/workflows/ci.yml
| name: CI | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| pull_request: | ||
| branches: [main] | ||
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.ref }} | ||
| cancel-in-progress: true |
There was a problem hiding this comment.
Set explicit minimal permissions to reduce attack surface.
The workflow uses GitHub's default permissions, which grant read-write access to multiple scopes. CI workflows typically only need read access to repository contents.
🔒 Recommended fix to add explicit permissions
name: CI
+permissions:
+ contents: read
+
on:
push:
branches: [main]📝 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.
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| name: CI | |
| permissions: | |
| contents: read | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true |
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 1-115: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block
(excessive-permissions)
🤖 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/ci.yml around lines 1 - 11, The CI workflow lacks explicit
permission declarations and relies on GitHub's default permissions which grant
excessive read-write access. Add a `permissions` block at the top level of the
workflow configuration after the `on` section and before the `concurrency`
section to explicitly declare minimal required permissions. For a CI workflow
that only needs to access repository contents, set `contents: read` to restrict
access to read-only operations on the repository, reducing the potential attack
surface if the workflow is compromised.
Source: Linters/SAST tools
| name: Contract build & test | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 |
There was a problem hiding this comment.
Add persist-credentials: false to checkout action for defense in depth.
Without this setting, the GITHUB_TOKEN remains accessible to subsequent steps. If the checked-out code contains malicious scripts, they could abuse the token.
🔒 Recommended fix
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v4
+ with:
+ persist-credentials: false📝 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.
| - uses: actions/checkout@v4 | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false |
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 18-18: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 18-18: 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/ci.yml at line 18, The actions/checkout@v4 action is
missing the persist-credentials parameter which leaves the GITHUB_TOKEN
accessible to subsequent workflow steps, creating a security vulnerability. Add
persist-credentials: false as an option to the checkout action to ensure the
GITHUB_TOKEN is not retained after the checkout step completes, preventing
potential token abuse if the checked-out code contains malicious scripts.
Source: Linters/SAST tools
| - name: Cache cargo registry | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: | | ||
| ~/.cargo/registry | ||
| ~/.cargo/git | ||
| contract/target | ||
| key: ${{ runner.os }}-cargo-${{ hashFiles('contract/Cargo.lock') }} | ||
| restore-keys: ${{ runner.os }}-cargo- |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check for Cargo.lock files in contract directories
fd -t f '^Cargo\.lock$' contract/Repository: Stellar-Ecosystem/lodestar
Length of output: 117
Update cache key to include both Cargo.lock files.
The cache key only hashes contract/Cargo.lock, but the repository contains two Cargo.lock files: contract/Cargo.lock and contract/agents/Cargo.lock. Dependency changes in contract/agents/ won't invalidate the cache, leading to stale cached dependencies.
Update the cache key to include both files:
key: ${{ runner.os }}-cargo-${{ hashFiles('contract/Cargo.lock', 'contract/agents/Cargo.lock') }}
🧰 Tools
🪛 zizmor (1.25.2)
[error] 26-26: 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/ci.yml around lines 25 - 33, The cache key in the "Cache
cargo registry" step only includes the hash of contract/Cargo.lock, but there
are two Cargo.lock files in the repository that can affect dependencies:
contract/Cargo.lock and contract/agents/Cargo.lock. Update the key field in the
with section to include both Cargo.lock files in the hashFiles function so that
cache invalidation occurs when either file changes, preventing stale cached
dependencies from contract/agents.
| name: Backend tests | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 |
There was a problem hiding this comment.
Add persist-credentials: false to checkout action for defense in depth.
Same security concern as in the contract-build job. The GITHUB_TOKEN should not persist into subsequent steps.
🔒 Recommended fix
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v4
+ with:
+ persist-credentials: false🧰 Tools
🪛 zizmor (1.25.2)
[warning] 55-55: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 55-55: 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/ci.yml at line 55, The actions/checkout@v4 action is
missing the persist-credentials: false parameter, which allows the GITHUB_TOKEN
to persist into subsequent workflow steps creating a security vulnerability. Add
the persist-credentials: false configuration option to the checkout action to
ensure the GITHUB_TOKEN does not remain available in downstream steps.
Source: Linters/SAST tools
| - name: Use Node.js 20 | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '20' | ||
| cache: 'npm' | ||
| cache-dependency-path: backend/package-lock.json |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check for package-lock.json in backend directory
fd -t f '^package-lock\.json$' backend/Repository: Stellar-Ecosystem/lodestar
Length of output: 52
🏁 Script executed:
# Check for package.json files in the repo
fd -t f '^package\.json$'Repository: Stellar-Ecosystem/lodestar
Length of output: 132
🏁 Script executed:
# Check for package-lock.json files anywhere in the repo
fd -t f '^package-lock\.json$'Repository: Stellar-Ecosystem/lodestar
Length of output: 52
🏁 Script executed:
# Check the backend directory structure
ls -la backend/ 2>/dev/null | head -20Repository: Stellar-Ecosystem/lodestar
Length of output: 469
🏁 Script executed:
# Check the CI workflow file to see full context and understand the setup
cat -n .github/workflows/ci.ymlRepository: Stellar-Ecosystem/lodestar
Length of output: 4303
backend/package-lock.json does not exist. The npm cache configuration references backend/package-lock.json, but this file is not present in the repository. Without a package-lock.json, the cache will not be used effectively, and npm ci may not guarantee reproducible builds. Either generate a package-lock.json by running npm install in the backend directory, or remove the cache-dependency-path configuration to disable caching for this job.
(Note: The same issue exists in the frontend-check job at line 91 with frontend/package-lock.json.)
🧰 Tools
🪛 zizmor (1.25.2)
[error] 58-58: 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/ci.yml around lines 57 - 62, The `cache-dependency-path`
configuration in the Node.js setup action references `backend/package-lock.json`
and `frontend/package-lock.json` files that do not exist in the repository,
which prevents effective npm caching. Either generate these package-lock.json
files by running `npm install` in the backend and frontend directories
respectively to create them, or remove the `cache-dependency-path` properties
from both the setup-node action in the main job (lines 57-62) and the
frontend-check job (line 91) to disable dependency path caching if package-lock
files are not needed for the project.
| name: Frontend typecheck & build | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 |
There was a problem hiding this comment.
Add persist-credentials: false to checkout action for defense in depth.
Same security concern as in the other jobs. The GITHUB_TOKEN should not persist into subsequent steps.
🔒 Recommended fix
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v4
+ with:
+ persist-credentials: false📝 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.
| - uses: actions/checkout@v4 | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false |
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 84-84: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 84-84: 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/ci.yml at line 84, The checkout action at line 84 does not
disable credential persistence, which poses a security risk by allowing the
GITHUB_TOKEN to persist into subsequent workflow steps. Add the
`persist-credentials: false` parameter to the `actions/checkout@v4` action to
ensure that the GitHub token is not available to downstream steps, maintaining
proper defense in depth for token management.
Source: Linters/SAST tools
| - name: Use Node.js 20 | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '20' | ||
| cache: 'npm' | ||
| cache-dependency-path: frontend/package-lock.json |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check for package-lock.json in frontend directory
fd -t f '^package-lock\.json$' frontend/Repository: Stellar-Ecosystem/lodestar
Length of output: 52
🏁 Script executed:
# Check if frontend directory exists and list its contents
if [ -d frontend ]; then
echo "=== Frontend directory contents ==="
ls -la frontend/ | head -20
else
echo "Frontend directory does not exist"
fi
echo ""
echo "=== Searching for package-lock.json anywhere in the repo ==="
fd -t f 'package-lock\.json'
echo ""
echo "=== Checking root directory for package-lock.json or package.json ==="
ls -la | grep -E 'package-lock|package\.json'Repository: Stellar-Ecosystem/lodestar
Length of output: 1207
🏁 Script executed:
# Search for any lock files (npm, yarn, pnpm, etc)
echo "=== Searching for lock files ==="
fd -t f '\.(lock|lock\.json)$'
echo ""
echo "=== Check what's in .npmrc ==="
cat frontend/.npmrc
echo ""
echo "=== Check package.json to understand dependencies ==="
cat frontend/package.jsonRepository: Stellar-Ecosystem/lodestar
Length of output: 1340
🏁 Script executed:
# Check the full CI workflow file to understand the context better
echo "=== CI workflow file (lines 80-95) ==="
sed -n '80,95p' .github/workflows/ci.yml
echo ""
echo "=== Check if there are any other references to package-lock in the workflow ==="
grep -n "package-lock" .github/workflows/ci.ymlRepository: Stellar-Ecosystem/lodestar
Length of output: 726
🏁 Script executed:
# Check if backend/package-lock.json exists
echo "=== Checking backend directory ==="
if [ -d backend ]; then
ls -la backend/ | grep -E 'package-lock|package\.json'
else
echo "Backend directory does not exist"
fi
echo ""
echo "=== Full workflow for context ==="
cat .github/workflows/ci.ymlRepository: Stellar-Ecosystem/lodestar
Length of output: 3637
Remove the cache-dependency-path configuration or generate package-lock.json files.
The npm cache configuration references frontend/package-lock.json, which does not exist in the repository. Without the lock file present when the action runs, GitHub Actions cannot establish an effective cache. Either remove the cache-dependency-path line to use default caching behavior, or ensure package-lock.json is committed to the repository.
🧰 Tools
🪛 zizmor (1.25.2)
[error] 87-87: 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/ci.yml around lines 86 - 91, The setup-node action step
references a non-existent frontend/package-lock.json file in the
cache-dependency-path configuration, which prevents npm caching from working
correctly. Either remove the cache-dependency-path line entirely to allow the
action to use its default caching behavior, or generate and commit the
package-lock.json file to the frontend directory. Choose the approach that
aligns with your project's dependency management strategy.
Closes #145
Summary
cargo testfor both registry and agents contracts, thencargo check --target wasm32-unknown-unknownto catch WASM incompatibilities without a full Soroban CLI buildnpm ci+npm test(vitest) with minimal stub env vars soconfig.js's required-variable guard passes without real credentialsnpm ci+tsc --noEmit(full TypeScript) +next lint+next buildwith stubNEXT_PUBLIC_env varsAll three jobs run in parallel;
concurrencygroup cancels in-progress runs on force-push to save minutes.Test plan
contract/src/lib.rs— contract-build failstsc --noEmitSummary by CodeRabbit