Skip to content

feat(dashmate): configure docker build args via config#3764

Merged
shumkov merged 7 commits into
v3.1-devfrom
feat/dashmate-build-args
Jun 1, 2026
Merged

feat(dashmate): configure docker build args via config#3764
shumkov merged 7 commits into
v3.1-devfrom
feat/dashmate-build-args

Conversation

@shumkov
Copy link
Copy Markdown
Collaborator

@shumkov shumkov commented May 28, 2026

Issue being fixed or feature implemented

Adds a dockerBuild.buildArgs map to the dashmate config schema so per-image Docker build args (e.g. CARGO_BUILD_PROFILE, SDK_TEST_DATA) can be pinned per config and forwarded to the image build. Previously the only way to set these at build time was to export shell envs on every invocation or hand-edit the compose YAML — neither survives yarn setup cleanly.

What was done?

  • Schema (configJsonSchema.js): dockerBuild.buildArgs is { [string]: string }, with keys constrained to env-var identifiers (^[A-Za-z_][A-Za-z0-9_]*$).
  • Config helpers (Config.js, commands/config/set.js): schema-aware path validation (Config.isSchemaPathAllowed) so map-shaped paths like platform.drive.abci.docker.build.buildArgs.SDK_TEST_DATA are accepted — the old existence-based pre-check rejected any key that didn't exist yet. Paths with empty segments are rejected.
  • Forwarding via dynamic-compose (templates/dynamic-compose.yml.dot): each config's buildArgs render directly into that config's generated dynamic-compose.yml as build.args entries, with values JSON.stringify-escaped so a quote/backslash/newline stays valid YAML. Dashmate config is the single source of truth — there is no shell-env passthrough.
  • Default config + migration: buildArgs: {} placeholder on both the drive.abci and dapi.rsDapi build blocks; a 3.1.0 migration backfills the field on pre-existing configs.

Yarn-script side (setup_local_network.sh): pins SDK_TEST_DATA="true" per local_N (the genesis test-data flag). CARGO_BUILD_PROFILE is intentionally not pinned — operators set it per config when they want a release bake:

dashmate config set --config=local_1 platform.drive.abci.docker.build.buildArgs.CARGO_BUILD_PROFILE '"release"'

Release is strongly recommended when SDK_TEST_DATA is on: the genesis shielded-pool seeding runs at InitChain (runtime), and a release-compiled binary runs that Sinsemilla work ~10× faster than a debug build.

⚠️ Build args are sourced only from dashmate config. A shell-only CARGO_BUILD_PROFILE=release yarn start is not forwarded to the build — persist it with dashmate config set …buildArgs.CARGO_BUILD_PROFILE instead.

How Has This Been Tested?

  • Config.spec.js — unit tests for schema-aware path traversal (typed properties, additionalProperties maps, $ref descent, leaf-primitive and empty-segment rejection) plus a regression test for the original buildArgs.SDK_TEST_DATA failure.
  • dynamicComposeBuildArgs.spec.js — renders the template and asserts build.args are emitted per service, omitted when buildArgs is empty, and YAML-escaped (a js-yaml round-trip on a value containing a quote, backslash and newline).
  • Manual end-to-end: yarn setup local --node-count=3 …, then a release bake via dashmate config set …CARGO_BUILD_PROFILE '"release"', produces a release drive:local image with SDK_TEST_DATA seeding active.

Breaking Changes

None — the schema change is additive. Existing dashmate configs without buildArgs are backfilled to an empty map by the 3.1.0 migration and continue to work unchanged.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

Adds a `dockerBuild.buildArgs` map on the dashmate config schema so
per-image Docker build args can be pinned in the config file (and
overridden per-invocation through shell env), without having to bake
them into the compose YAML by hand or into yarn scripts.

Pieces:

- **Schema** (`src/config/configJsonSchema.js`): `dockerBuild.buildArgs`
  is `{ [string]: string }`. Common keys today are `CARGO_BUILD_PROFILE`
  (Rust profile) and `SDK_TEST_DATA` (compile-time cfg flag), but it's
  open-ended.
- **Config helpers** (`src/config/Config.js`,
  `src/commands/config/set.js`): traverse the schema correctly when the
  user does `dashmate config set
  platform.drive.abci.docker.build.buildArgs.SDK_TEST_DATA true`
  (the original pre-check rejected map-shaped paths; this PR fixes that
  and pins it with `Config.spec.js::buildArgs`).
- **Env forwarding** (`src/config/generateEnvsFactory.js`): both
  `platform.drive.abci.docker.build.buildArgs` and
  `platform.dapi.rsDapi.docker.build.buildArgs` are merged and exported
  as env vars at compose-spawn time so the compose `${KEY:-default}`
  substitution picks them up. Dashmate config is the single source of
  truth — `process.env[key]` is not consulted as fallback.
- **Compose YAML** (`docker-compose.build.drive_abci.yml`,
  `docker-compose.build.rs-dapi.yml`): forward `CARGO_BUILD_PROFILE` to
  the Dockerfile `ARG` (`${CARGO_BUILD_PROFILE:-dev}`).
- **Default config**
  (`configs/defaults/getBaseConfigFactory.js`): `buildArgs: {}` on both
  rs-dapi and drive-abci build blocks so the schema accepts overrides.

Yarn-script side (`scripts/setup_local_network.sh`):

- The local-network setup script pins `SDK_TEST_DATA=true` on each
  `local_N` config so the genesis SDK test data runs at devnet
  bring-up. `CARGO_BUILD_PROFILE` is deliberately NOT pinned in the
  script — operators set release per-invocation via
  `CARGO_BUILD_PROFILE=release yarn start`, or persist it via
  `yarn dashmate config set` directly. Keeping the profile out of the
  script means the same `yarn setup` works for both dev iteration
  loops (default `dev` profile) and SDK_TEST_DATA bakes (release).

Docs:

- `docs/shielded-seeder-performance.md` documents why release profile
  is recommended when SDK_TEST_DATA is on at the default N=1_000_000
  bake (~13× faster Sinsemilla on release vs debug). Referenced from
  `configJsonSchema.js` and `getBaseConfigFactory.js`.

Tests: `Config.spec.js` adds 15 cases covering the map-shaped path
traversal — including a regression test for the original
`buildArgs.SDK_TEST_DATA` failure.
@shumkov shumkov requested a review from QuantumExplorer as a code owner May 28, 2026 12:57
@github-actions github-actions Bot added this to the v3.1.0 milestone May 28, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Per-image Docker build arguments are forwarded from platform config into a generated dynamic-compose.yml as build.args. Schema comments, defaults, migrations, compose templates, rendering tests, env-generation behavior, Config path validation, and local setup scripts were updated to reflect this flow.

Changes

Docker Build Arguments Configuration Flow

Layer / File(s) Summary
Schema documentation and default buildArgs initialization
packages/dashmate/src/config/configJsonSchema.js, packages/dashmate/configs/defaults/getBaseConfigFactory.js, packages/dashmate/configs/getConfigFileMigrationsFactory.js
Document dockerBuild.buildArgs as forwarded into dynamic-compose.yml build.args, add buildArgs: {} defaults for rs-dapi and drive.abci, and expand the 3.1.0 migration backfill comments.
Docker-compose template documentation
packages/dashmate/docker-compose.build.drive_abci.yml, packages/dashmate/docker-compose.build.rs-dapi.yml
Add inline comments to compose templates noting dashmate injects per-config build args from platform config into the generated dynamic-compose at compose time.
Dynamic-compose template rendering tests
packages/dashmate/test/unit/templates/dynamicComposeBuildArgs.spec.js
Add helper and tests that render dynamic-compose.yml.dot, asserting drive_abci and rs_dapi build.args render correctly, special-character escaping round-trips, and empty buildArgs conditionally omit build sections.
Implementation flow redirection and local setup
packages/dashmate/src/config/generateEnvsFactory.js, packages/dashmate/src/config/Config.js, packages/dashmate/test/unit/config/Config.spec.js, scripts/setup_local_network.sh
Remove forwarding of buildArgs into generated envs (note added); reject config paths with empty dot segments in schema checks and add tests; update local network setup to set platform.drive.abci.docker.build.buildArgs.SDK_TEST_DATA (JSON-quoted) per node and stop pinning CARGO_BUILD_PROFILE.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • QuantumExplorer
  • PastaPastaPasta

Poem

🐰 I nudge the args from config to compose,
Quoted strings and tricky chars in my nose.
Templates knit YAML, tests give a wink,
Docker queues builds — quicker than you think.
Hop, hop, the CI carrots we chose.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(dashmate): configure docker build args via config' clearly and concisely describes the main change—adding support for configuring Docker build arguments through the dashmate config system.
Docstring Coverage ✅ Passed Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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 feat/dashmate-build-args

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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
packages/dashmate/test/unit/config/Config.spec.js (1)

87-102: ⚡ Quick win

Add a regression test for empty path segments (a..b, a.b.).

Current edge-case tests miss malformed dotted paths with empty segments, which are important for the new schema walker behavior.

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

In `@packages/dashmate/test/unit/config/Config.spec.js` around lines 87 - 102, Add
regression tests to cover malformed dotted paths with empty segments for
Config.isSchemaPathAllowed: add assertions that
Config.isSchemaPathAllowed('a..b') and Config.isSchemaPathAllowed('a.b.') (and
optionally '.a' and 'a..') return false so the schema walker rejects empty path
segments; place them alongside the existing edge cases in the 'edge cases'
describe block near the other isSchemaPathAllowed tests to ensure these
malformed paths are explicitly covered.
🤖 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 `@docs/shielded-seeder-performance.md`:
- Line 44: Update the docs to match the implementation: replace references to
platform.drive.abci.docker.build.cargoBuildProfile with the actual config key
platform.drive.abci.docker.build.buildArgs.CARGO_BUILD_PROFILE; remove the claim
that scripts/setup_local_network.sh sets or restores CARGO_BUILD_PROFILE and
instead document that scripts/setup_local_network.sh only sets
SDK_TEST_DATA=true (which is auto-pinned), and state that CARGO_BUILD_PROFILE is
optional and must be set by the user either per-invocation or in their config if
they desire a non-default build profile.

In `@packages/dashmate/src/config/Config.js`:
- Around line 70-72: In isSchemaPathAllowed, add a validation after splitting
the dot-path that rejects any empty segments so paths like "foo." or "a..b"
return false; locate the split operation (path.split('.')) inside the
isSchemaPathAllowed method and ensure you check every segment for === '' (or
length === 0) and return false if any are empty before continuing the existing
allowed-key checks.

In `@packages/dashmate/src/config/configJsonSchema.js`:
- Around line 49-52: The buildArgs object currently allows any property name
(via additionalProperties) so invalid or empty keys can slip through; update the
schema for buildArgs to restrict property names to valid environment-variable
identifiers by replacing additionalProperties with patternProperties using a
regex like ^[A-Z_][A-Z0-9_]*$ for keys and keep the value type as string, and
set additionalProperties: false to reject any names that don't match; target the
buildArgs schema block to apply this change.

In `@packages/dashmate/src/config/generateEnvsFactory.js`:
- Around line 124-130: The loop copying mergedBuildArgs into envs can overwrite
reserved runtime keys; update the assignment in the block that iterates
mergedBuildArgs (the for..of using mergedBuildArgs, getBuildArgs) to skip any
keys in a reserved set (e.g.,
["COMPOSE_FILE","CONFIG_NAME","CONFIG_PATH","NODE_ENV","PATH"] or whatever
project-specific core keys) and optionally log or warn when a user-provided
buildArg is ignored; leave non-reserved keys assigned to envs as before.

---

Nitpick comments:
In `@packages/dashmate/test/unit/config/Config.spec.js`:
- Around line 87-102: Add regression tests to cover malformed dotted paths with
empty segments for Config.isSchemaPathAllowed: add assertions that
Config.isSchemaPathAllowed('a..b') and Config.isSchemaPathAllowed('a.b.') (and
optionally '.a' and 'a..') return false so the schema walker rejects empty path
segments; place them alongside the existing edge cases in the 'edge cases'
describe block near the other isSchemaPathAllowed tests to ensure these
malformed paths are explicitly covered.
🪄 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

Run ID: 17f30280-ab11-4adf-9e82-ca15acf967cc

📥 Commits

Reviewing files that changed from the base of the PR and between 2c9e9af and 66e0d6d.

📒 Files selected for processing (10)
  • docs/shielded-seeder-performance.md
  • packages/dashmate/configs/defaults/getBaseConfigFactory.js
  • packages/dashmate/docker-compose.build.drive_abci.yml
  • packages/dashmate/docker-compose.build.rs-dapi.yml
  • packages/dashmate/src/commands/config/set.js
  • packages/dashmate/src/config/Config.js
  • packages/dashmate/src/config/configJsonSchema.js
  • packages/dashmate/src/config/generateEnvsFactory.js
  • packages/dashmate/test/unit/config/Config.spec.js
  • scripts/setup_local_network.sh

Comment thread docs/shielded-seeder-performance.md Outdated
Comment thread packages/dashmate/src/config/Config.js
Comment thread packages/dashmate/src/config/configJsonSchema.js
Comment thread packages/dashmate/src/config/generateEnvsFactory.js Outdated
Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

Code Review

PR adds a generic buildArgs map to dashmate's dockerBuild schema and wires it through to docker compose, plus a set.js fix to support map-shaped (additionalProperties) schema paths. The implementation is sound — coerceTypes in AJV correctly handles boolean→string coercion for config set ... true flows, and tests for isSchemaPathAllowed are thorough. The remaining issues are documentation inconsistencies introduced by this PR: contradictory claims about shell-env precedence and an invalid config-path reference.

🟡 3 suggestion(s) | 💬 2 nitpick(s)

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `docs/shielded-seeder-performance.md`:
- [SUGGESTION] docs/shielded-seeder-performance.md:44: Doc references a config path that does not exist
  Line 44 says the release profile is plumbed through dashmate as `platform.drive.abci.docker.build.cargoBuildProfile`, but the schema in `configJsonSchema.js` only adds a generic `buildArgs` map — there is no `cargoBuildProfile` field. The same document uses the correct path (`buildArgs.CARGO_BUILD_PROFILE`) later on lines 113 and 121. An operator following the line-44 instruction will hit `InvalidOptionPathError` or set an inert field.

In `packages/dashmate/src/config/configJsonSchema.js`:
- [SUGGESTION] packages/dashmate/src/config/configJsonSchema.js:35-48: Schema comment claims shell env overrides config, but the opposite is true
  The schema comment says `Shell env overrides any value set here (so CARGO_BUILD_PROFILE=release yarn start wins per-invocation)`. The actual precedence is the reverse: `DockerCompose.js#createOptionsWithEnvs` (lines 676–679) constructs the spawn env as `{ ...process.env, ...envs }`, so the values `generateEnvsFactory` injects from `buildArgs` shadow same-named shell env vars. The implementation comment in `generateEnvsFactory.js` (lines 112–116) and the PR design (dashmate config = single source of truth) confirm dashmate wins. Shell env still flows through as a fallback for keys NOT set in `buildArgs`, but it does not override. Reconcile the schema comment with the implementation, or callers will be surprised when `CARGO_BUILD_PROFILE=release yarn start` is silently dropped.

In `packages/dashmate/src/config/generateEnvsFactory.js`:
- [SUGGESTION] packages/dashmate/src/config/generateEnvsFactory.js:112-116: Comment overstates the single-source-of-truth claim
  The comment says `do NOT fall back to process.env[key]. Operators who need a per-invocation override should yarn dashmate config set ... rather than FOO=bar yarn start.` In practice `DockerCompose.js#createOptionsWithEnvs` still spreads `process.env` first into the spawn env, so shell-provided values do reach docker-compose for any buildArg key the dashmate config has not set. The accurate semantics are: dashmate config wins on collision; shell env still works as a fallback for unset keys. Stating this precisely prevents a future contributor from removing the `process.env` spread in the name of single-source enforcement, which would silently break existing `FOO=bar yarn start` patterns.

Comment thread docs/shielded-seeder-performance.md Outdated
Comment thread packages/dashmate/src/config/configJsonSchema.js Outdated
Comment thread packages/dashmate/src/config/generateEnvsFactory.js Outdated
Comment thread scripts/setup_local_network.sh Outdated
Comment thread packages/dashmate/src/config/generateEnvsFactory.js Outdated
…rough

Replaces the env-var-based forwarding (which hardcoded every supported
arg key in `docker-compose.build.*.yml` as `${KEY:-default}` and
re-exported them from `generateEnvsFactory`) with a generic
dynamic-compose render path. Now `dockerBuild.buildArgs` is open-ended
on the schema and any key/value the operator pins via `dashmate config
set platform.{drive.abci|dapi.rsDapi}.docker.build.buildArgs.X Y` is
emitted as a `services.<svc>.build.args.X: "Y"` entry in the
per-config `dynamic-compose.yml` and merged with the static build
compose by docker compose.

Changes:

- **dynamic-compose.yml.dot**: iterate over
  `platform.drive.abci.docker.build.buildArgs` and
  `platform.dapi.rsDapi.docker.build.buildArgs` and emit a `build.args`
  block per service. The drive_abci service block is only emitted when
  either driveLogs or driveBuildArgs has entries; rs_dapi gains a
  conditional build block alongside its existing expose stanza.
- **docker-compose.build.drive_abci.yml** /
  **docker-compose.build.rs-dapi.yml**: drop the hardcoded
  `CARGO_BUILD_PROFILE: ${CARGO_BUILD_PROFILE:-dev}` and (for
  drive_abci) `SDK_TEST_DATA: ${SDK_TEST_DATA}` lines. Static compose
  now only carries args sourced from shell env (sccache config); all
  config-sourced args flow through dynamic-compose.
- **generateEnvsFactory.js**: drop the env-var passthrough block.
- **configJsonSchema.js** / **getBaseConfigFactory.js**: trim the
  comment to one line — the schema doesn't need example keys or doc
  references.
- **getConfigFileMigrationsFactory.js**: 3.1.0 migration backfills
  `buildArgs: {}` onto both build blocks for pre-existing configs.
- **scripts/setup_local_network.sh**: replace the verbose multi-line
  comment with one sentence.

Removed `docs/shielded-seeder-performance.md` — it was added by mistake
to this PR (lives with the shielded-pool work, not the dashmate
plumbing).

Tests:
- `dynamicComposeBuildArgs.spec.js`: 3 new tests covering drive_abci
  emission, rs_dapi emission, and the empty-buildArgs no-op path.
- `Config.spec.js`: 15 tests still passing.
- 101/101 unit tests pass on `yarn mocha test/unit/**/*.spec.js`.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/dashmate/test/unit/templates/dynamicComposeBuildArgs.spec.js (1)

15-17: ⚡ Quick win

Restore doT templateSettings.strip after mutating it in the test
In packages/dashmate/test/unit/templates/dynamicComposeBuildArgs.spec.js, render() sets dot.templateSettings.strip = false and doesn’t restore the previous value, leaking global doT configuration across tests. Save the prior value and restore it in a finally block after rendering.

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

In `@packages/dashmate/test/unit/templates/dynamicComposeBuildArgs.spec.js` around
lines 15 - 17, The test mutates global doT config by setting
dot.templateSettings.strip = false in render(); capture the original value
before changing it (e.g., const prev = dot.templateSettings.strip), perform the
template work (reading TEMPLATE_PATH and calling dot.template), and then restore
the original setting in a finally block (dot.templateSettings.strip = prev) so
the mutation does not leak to other tests; update the render() helper in
dynamicComposeBuildArgs.spec.js to implement this save/restore around the tpl/fn
template operations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/dashmate/test/unit/templates/dynamicComposeBuildArgs.spec.js`:
- Around line 7-12: The test uses underscored locals __filename and __dirname
which violate camelCase lint rules; rename them to camelCase (e.g., filename and
dirname or filePath and dirPath) and update their initializations (replace
__filename = fileURLToPath(import.meta.url) and __dirname =
path.dirname(__filename) with the new names) and any subsequent references
(including TEMPLATE_PATH resolution) so all identifiers are camelCase and the
tests still resolve the template path correctly.

---

Nitpick comments:
In `@packages/dashmate/test/unit/templates/dynamicComposeBuildArgs.spec.js`:
- Around line 15-17: The test mutates global doT config by setting
dot.templateSettings.strip = false in render(); capture the original value
before changing it (e.g., const prev = dot.templateSettings.strip), perform the
template work (reading TEMPLATE_PATH and calling dot.template), and then restore
the original setting in a finally block (dot.templateSettings.strip = prev) so
the mutation does not leak to other tests; update the render() helper in
dynamicComposeBuildArgs.spec.js to implement this save/restore around the tpl/fn
template operations.
🪄 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

Run ID: fa58173b-1c8b-4acf-ace9-42a79a40edc1

📥 Commits

Reviewing files that changed from the base of the PR and between 66e0d6d and 868ae52.

⛔ Files ignored due to path filters (1)
  • packages/dashmate/templates/dynamic-compose.yml.dot is excluded by !**/*.dot
📒 Files selected for processing (7)
  • packages/dashmate/configs/defaults/getBaseConfigFactory.js
  • packages/dashmate/configs/getConfigFileMigrationsFactory.js
  • packages/dashmate/docker-compose.build.drive_abci.yml
  • packages/dashmate/docker-compose.build.rs-dapi.yml
  • packages/dashmate/src/config/configJsonSchema.js
  • packages/dashmate/test/unit/templates/dynamicComposeBuildArgs.spec.js
  • scripts/setup_local_network.sh
✅ Files skipped from review due to trivial changes (1)
  • packages/dashmate/docker-compose.build.rs-dapi.yml
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/dashmate/configs/defaults/getBaseConfigFactory.js
  • packages/dashmate/src/config/configJsonSchema.js
  • scripts/setup_local_network.sh

Comment thread packages/dashmate/test/unit/templates/dynamicComposeBuildArgs.spec.js Outdated
Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

Code Review

Latest delta moves buildArgs forwarding from env passthrough into the per-config dynamic-compose.yml template and rewrites the schema/comments accordingly. All five prior findings are resolved. One blocking regression remains: dashmate config set ...buildArgs.* true (used by this PR's own scripts/setup_local_network.sh) JSON-parses true into a boolean, which fails schema validation that now requires string-typed values. A secondary suggestion covers unescaped YAML interpolation of buildArgs values.

🔴 1 blocking | 🟡 1 suggestion(s)

1 additional finding(s) omitted (not in diff).

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `packages/dashmate/src/commands/config/set.js`:
- [BLOCKING] packages/dashmate/src/commands/config/set.js:54-60: `dashmate config set ...buildArgs.SDK_TEST_DATA true` is rejected because the CLI JSON-parses the value into a boolean
  `configJsonSchema.js` lines 40–42 now requires every `docker.build.buildArgs.*` entry to be `type: 'string'`, but `set.js` unconditionally runs `JSON.parse(optionValue)` before calling `config.set(...)`. For the inputs introduced by this PR — `scripts/setup_local_network.sh` line 24 (`... buildArgs.SDK_TEST_DATA "true"`) and the analogous `CARGO_BUILD_PROFILE release` example — the shell strips the quotes and dashmate receives the bare token `true`/`release`. `JSON.parse("true")` returns boolean `true`, `Config.set` runs AJV validation (Config.js:151), and AJV rejects the boolean against the string-typed `additionalProperties`, throwing `InvalidOptionError`. The setup script in this same PR therefore fails at line 23–24, and the documented operator workflow is broken end-to-end. Skip JSON-parsing for the open-string-map buildArgs path (or, equivalently, fall back to the raw string when the parsed value's type doesn't match the schema).

In `packages/dashmate/templates/dynamic-compose.yml.dot`:
- [SUGGESTION] packages/dashmate/templates/dynamic-compose.yml.dot:30: buildArgs values are interpolated into YAML without escaping
  Lines 30 and 58 render each pair as `{{=pair[0]}}: "{{=pair[1]}}"`. doT's `{{=...}}` is raw interpolation and the schema only constrains values to `type: 'string'` with no character restriction, so a value containing `"`, `\`, or a newline produces invalid or altered YAML that fails the next dashmate render with a confusing parse error rather than at `config set` time. The PR opens this surface as a public, open-ended `Record<string, string>` API, so worth either YAML-escaping (single-quoted form with doubled single quotes) or constraining values via a safe-character regex in the schema.

Comment thread packages/dashmate/templates/dynamic-compose.yml.dot Outdated
shumkov added 2 commits June 1, 2026 14:12
Resolve buildArgs feature collision: base v3.1-dev independently shipped the
same feature via env-passthrough (generateEnvsFactory). Kept this branch's
dynamic-compose mechanism instead, dropping the env-passthrough block, per
the "drop env passthrough" design (commit 868ae52).

Conflict resolutions:
- compose build files: take dynamic-compose approach (no explicit
  SDK_TEST_DATA/CARGO_BUILD_PROFILE ${...} substitutions)
- configJsonSchema.js: dynamic-compose comment + kept base's stricter
  propertyNames pattern validation
- getBaseConfigFactory.js / migrations: buildArgs:{} backfill
- setup_local_network.sh: took base (JSON-string quoting + release pinning
  required at the new N=1,000,000 seed default)
- generateEnvsFactory.js: removed base's env-passthrough block (single
  source of truth is dynamic-compose.yml)

18/18 dashmate unit tests pass.
The local-network setup script no longer forces CARGO_BUILD_PROFILE=release
on each masternode's drive-abci build. Operators set the profile per-config
when they want a release bake; SDK_TEST_DATA seeding still defaults on.

Note: with env-passthrough removed (single source of truth is
dynamic-compose buildArgs) and no profile pinned, the Dockerfile ARG default
(CARGO_BUILD_PROFILE=dev) applies unless set via `dashmate config set`.
@thepastaclaw
Copy link
Copy Markdown
Collaborator

thepastaclaw commented Jun 1, 2026

✅ Review complete (commit 59cceeb)

Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

Code Review

Latest delta removes the CARGO_BUILD_PROFILE=release pin from the local setup script and JSON-quotes SDK_TEST_DATA so the path/value combo passes validation. Two prior findings carry forward (set.js still JSON-parses values before schema validation; buildArgs values still render into YAML unescaped). One new regression: with env forwarding and ${CARGO_BUILD_PROFILE:-dev} both removed, the previously-documented CARGO_BUILD_PROFILE=release yarn start per-invocation override no longer reaches Docker builds.

🔴 1 blocking | 🟡 2 suggestion(s) | 💬 1 nitpick(s)

1 additional finding(s) omitted (not in diff).

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `packages/dashmate/src/commands/config/set.js`:
- [BLOCKING] packages/dashmate/src/commands/config/set.js:54-60: [Carried-forward — STILL VALID] `dashmate config set` JSON-parses build-arg values, so bare string values that look like JSON literals are rejected
  The path precheck was correctly swapped to `Config.isSchemaPathAllowed`, but `runWithDependencies` still unconditionally `JSON.parse`s every CLI value. Because `configJsonSchema.js` types `buildArgs` values as `{ type: 'string' }` (with `additionalProperties: { type: 'string' }`), any CLI invocation like `dashmate config set …buildArgs.CARGO_BUILD_PROFILE release` parses `release` fine (string) — but `dashmate config set …buildArgs.SDK_TEST_DATA true` parses to boolean `true` and is rejected by AJV. The new setup script works only because it passes `'"true"'` (a JSON-quoted string). This is the PR's new public API; documented use cases (`SDK_TEST_DATA`, plus future flag-style args like `1`/`0`/`null`) all collide with this typing. Either short-circuit JSON.parse for `…docker.build.buildArgs.…` paths, or fall back to the raw string when JSON.parse yields a value that fails schema validation as a string.

In `packages/dashmate/src/config/generateEnvsFactory.js`:
- [SUGGESTION] packages/dashmate/src/config/generateEnvsFactory.js:106-109: Shell-only `CARGO_BUILD_PROFILE=release yarn start` overrides no longer reach Docker builds
  This PR removes both halves of the previous shell-env passthrough: `generateEnvsFactory.js` explicitly stops forwarding `docker.build.buildArgs` into the compose environment, and `docker-compose.build.drive_abci.yml` / `docker-compose.build.rs-dapi.yml` drop their `CARGO_BUILD_PROFILE: ${CARGO_BUILD_PROFILE:-dev}` entries (confirmed in the diff against v3.1-dev). After this change, `CARGO_BUILD_PROFILE=release yarn start` is silently a no-op — the only working path is `dashmate config set …buildArgs.CARGO_BUILD_PROFILE '"release"'`. The setup script's own comment correctly tells operators to use `dashmate config set`, so the script is internally consistent, but the PR description still advertises the shell-env override. Either restore the `${CARGO_BUILD_PROFILE:-dev}` fallback in the two build compose files (so `dynamic-compose.yml` overrides win when set but the shell env still works otherwise), or update the PR description to drop the shell-env claim and point users at `dashmate config set` exclusively.

In `packages/dashmate/templates/dynamic-compose.yml.dot`:
- [SUGGESTION] packages/dashmate/templates/dynamic-compose.yml.dot:30: [Carried-forward — STILL VALID] buildArgs values are raw-interpolated into YAML without escaping or schema char restrictions
  Both render sites (`drive_abci` line 30, `rs_dapi` line 58) emit `{{=pair[0]}}: "{{=pair[1]}}"` with no escaping. `configJsonSchema.js` restricts keys via `propertyNames.pattern: '^[A-Za-z_][A-Za-z0-9_]*$'` but values are just `{ type: 'string' }` with no character restriction. A value containing `"`, `\`, or a newline (settable via `dashmate config set …buildArgs.FOO 'a"b'`) renders into malformed YAML and breaks the next compose invocation — there is no subsequent validation step over the generated `dynamic-compose.yml`. Operator-controlled input, so it's a robustness/UX concern rather than security. The cleanest fix is to mirror the key restriction onto values in the schema (any printable-ASCII regex that excludes `"`, `\`, and control chars easily covers realistic build args like `dev`/`release`/`true`/version/path strings). Alternatively, render values via `JSON.stringify` in the .dot template so YAML-quoting handles edge cases automatically.

Comment thread packages/dashmate/src/config/generateEnvsFactory.js
Comment thread packages/dashmate/templates/dynamic-compose.yml.dot Outdated
Comment thread packages/dashmate/configs/getConfigFileMigrationsFactory.js Outdated
Merge resolution left a double blank line that tripped
@stylistic/no-multiple-empty-lines in the dashmate lint job.
Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

Code Review

Incremental + cumulative review at 6f083eb (no new delta vs prior reviewed SHA). Reconciled all four prior findings: the migration blank-line was fixed; the YAML-escaping and shell-env-passthrough findings remain valid as suggestions; the set.js JSON.parse issue is downgraded — set.js is not in this PR's cumulative diff against origin/v3.1-dev and the PR ships an explicit workaround. No blocking issues; review action COMMENT.

🟡 2 suggestion(s)

1 additional finding(s) omitted (not in diff).

1 carried-forward finding(s) already raised on this PR; not re-posting as new inline comments.

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `packages/dashmate/src/config/generateEnvsFactory.js`:
- [SUGGESTION] packages/dashmate/src/config/generateEnvsFactory.js:106-109: [Carried-forward — STILL VALID] PR description still advertises shell-env CARGO_BUILD_PROFILE override, but env passthrough was removed
  `generateEnvsFactory.js` now explicitly stops forwarding `docker.build.buildArgs` into the compose environment (replaced with a NOTE comment), and `docker-compose.build.drive_abci.yml` / `docker-compose.build.rs-dapi.yml` no longer carry `CARGO_BUILD_PROFILE: ${CARGO_BUILD_PROFILE:-dev}`. Only values persisted into dashmate config land in `dynamic-compose.yml`, so a shell-only invocation like `CARGO_BUILD_PROFILE=release yarn start` is silently ignored. This contradicts the PR description's stated workflow ("per-invocation via CARGO_BUILD_PROFILE=release yarn start or persist via dashmate config set"). `scripts/setup_local_network.sh` already reflects the new reality by using `dashmate config set ...buildArgs.CARGO_BUILD_PROFILE '"release"'`. Either update the PR description to match (config-only workflow), or restore a narrowly-scoped env override for ergonomics. Documenting the operator workflow consistently matters because this is the headline UX of the change.

In `packages/dashmate/src/commands/config/set.js`:
- [SUGGESTION] packages/dashmate/src/commands/config/set.js:54-60: [Carried-forward — STILL VALID, downgraded] `dashmate config set` JSON-parses values; new buildArgs string-only schema rejects bare `true`/`false`/`1`/`null`
  `runWithDependencies` still runs `JSON.parse(optionValue)` with a string-fallback before `config.set(...)`. For the new `...docker.build.buildArgs.<KEY>` paths, `configJsonSchema.js` requires every value to be a string, so bare CLI inputs that happen to be valid JSON non-strings (`true`, `false`, `null`, `1`, `[…]`, `{…}`) are converted to non-strings and then rejected by AJV. Operators have to know to wrap such values in JSON quotes (e.g. `'"true"'`), which `scripts/setup_local_network.sh` already does. Note that `set.js` itself is NOT modified in this PR's cumulative diff against `origin/v3.1-dev`, so the JSON.parse logic predates this branch; however, the new buildArgs schema is what exposes the sharp edge for the PR's intended workflow. Typical CARGO_BUILD_PROFILE values (`dev`, `release`) parse cleanly via the catch-fallback, so this is an edge case rather than a workflow-breaker — hence suggestion rather than blocking. Consider bypassing JSON.parse for `…buildArgs.*` paths since the schema is string-only.

Comment thread packages/dashmate/src/config/generateEnvsFactory.js
Address PR review findings on the dynamic-compose buildArgs work:

- dynamic-compose.yml.dot: render build.args values via JSON.stringify so a
  value containing a quote/backslash/newline produces valid YAML instead of
  breaking the document. Ordinary values (e.g. "true") are unchanged.
- Config.isSchemaPathAllowed: reject paths with empty segments (a..b,
  trailing dot) so an empty key can't slip through a map's
  additionalProperties descent.
- setup_local_network.sh: correct the comment — SDK_TEST_DATA seeding runs at
  genesis (InitChain, runtime), not at docker build; release matters because
  the compiled binary runs that seeding ~10x faster.
- tests: YAML round-trip escaping test (js-yaml), empty-segment rejection
  test; rename dangle-underscore locals in the spec.
Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

Code Review

Latest delta resolves the YAML escaping issue (dynamic-compose.yml.dot now wraps buildArg values via JSON.stringify with a js-yaml round-trip regression test) and tightens isSchemaPathAllowed with an empty-segment guard plus unit coverage. The carried-forward 'dashmate config set foot-gun' finding from both agents does not survive verification: Config.ajv is constructed with coerceTypes: true, so bare CLI inputs true/false/1/null are silently coerced into strings before AJV validates against the buildArgs string schema. No in-scope issues remain.

…thAllowed

The empty-segment guard's `segments` shadowed the `segments` local inside
the resolveRef closure, tripping eslint no-shadow. Renamed to pathSegments.
Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

Code Review

Cumulative review of PR #3764 against v3.1-dev (head 59cceeb). The latest delta is a no-shadow lint rename in Config.isSchemaPathAllowed — zero behavior change. The full PR cleanly wires per-image docker build-args into dynamic-compose.yml for drive_abci/rs_dapi, with safe JSON.stringify rendering, env-var-identifier propertyNames constraint, empty-segment path rejection, and matching tests. No in-scope blockers or suggestions. One follow-up worth tracking separately about the shared dockerBuild schema exposing buildArgs on two sites that the renderer ignores.

@shumkov shumkov merged commit 2f48b2b into v3.1-dev Jun 1, 2026
16 checks passed
@shumkov shumkov deleted the feat/dashmate-build-args branch June 1, 2026 11:02
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.

2 participants