Repository navigation
Conversation
Upgrade maintained packages (got 14, octokit 22, ethers 6.17, image-size 2, inquirer 12, form-data 4, tar-fs 3, dotenv 16) and drop unused or deprecated ones (@dappnode/toolkit, dockerode, graphql, request, rimraf), clearing the known lockfile advisories. - Replace the toolkit APM client with a minimal local ApmRepository. - ESLint 10 flat config with typescript-eslint 8; lint no longer rewrites files. - Mocha 12 with tsx; live Docker/IPFS/Ethereum tests move to test:integration and run in a separate, non-blocking CI job. - Frozen installs in CI and a Node 20/22/24/26 test matrix. - Narrow js-yaml 4's unknown parse results in the compose, manifest and core-manifest readers. - Stream IPFS uploads from URLs through got instead of request. - Shared test fixtures.
Accept human-readable durations and bare integer strings as seconds (the documented --timeout 5000), pass numeric milliseconds through with 0 meaning no timeout, and reject invalid values instead of returning NaN.
Argument arrays now go through execFile, so upstream tags, branch names and image tags are passed literally instead of being interpolated into shell source. Commands accept a cwd, and streamed output is delivered as complete lines. The upstream tag allowlist keeps "@" (e.g. n8n@2.46.6).
A single renderer owns the terminal and shows numbered package/architecture stages with the last complete log lines. --skip_save no longer reports a successful build as an error, --all_variants prints the resolved variant names, and the build and publish handlers forward delete_old_pins.
Reject failed or signalled docker save/xz processes, bound export time and replace the archive atomically, so a broken export is never cached or uploaded. The compose path now pulls external images for the requested architecture, and the architecture check inspects that platform (--platform, with a fallback for Docker CLI < 28.1).
Wait for the overwrite prompt before writing anything, keep an existing Dockerfile unless --force is given, and derive the default package name from --dir.
Release files are now assembled from the same merged root and variant configuration that passed validation. - Setup wizards are read from JSON or YAML, merged by field id, validated against the schema and emitted as JSON. - Notifications are merged by correlationId. Within a matched wizard field or endpoint, a variant array replaces the root array instead of being merged by index. - Single release files (avatar, disclaimer, Prometheus targets, ...) come from the variant directory when present, otherwise from the root. Grafana dashboards are collected from both. - Values coerced by schema validation are listed in the "Validate files" step so source files can be fixed. - A single YAML manifest no longer hits the JSON-only template restriction. - Publishing keeps external upstream image references and recomputes the release directory for the new version. - Compose validation errors keep the "Invalid compose:" prefix. - The README documents the root and variant file rules.
- Old pins are deleted only after the replacement upload succeeded, and only for commits that are ancestors of the current commit. - On shallow CI checkouts the missing history is fetched once before checking. Commits that are still unknown are never unpinned. - Branch cleanup paginates Pinata pins, rechecks each allegedly deleted branch before unpinning, and handles template packages per variant.
Uploads report when all bytes are sent and then show the time spent waiting for pinning confirmation. Requests now abort only after 15 minutes without socket activity instead of at a fixed total, so slow but healthy uploads of large releases are not cut off. HTTP/2 is kept for IPFS uploads. The Swarm upload URL is relative to prefixUrl.
- GitHub releases upload every defined optional asset (setup wizard, schemas, UI, dashboards, ...). - Release preparation and upload errors fail the publish. An asset that a failed attempt already stored completely is accepted, and a partial one is replaced. - Branches and releases are paginated, and tag lookups match the exact ref. - GitHub action and bump-upstream builds pass --dir, the variants directory and the compose file name to the build, and read git metadata from the package directory.
A failed build printed its command output three or four times, and verbose logs repeated each line up to four times. - Shell errors carry a summary line plus the last 20 output lines; the full stdout and stderr stay on the error. - The terminal renderer keeps its own short per-task history, and a failed task shows only its title. - A verbose renderer logs every streamed line once and leaves the error to the CLI. - The CLI reports an error once and exits with code 1 instead of rethrowing. It also handles yargs' rejected parse promise, which Node otherwise printed as an unhandled rejection. When the log was already streamed only the summary is shown, and stack frames appear only with --verbose/--debug.
@octokit/request depends on content-type 3, which requires Node 22, so frozen installs failed on Node 20 (end of life since April 2026). The dappnode/workflows that run the SDK already use Node 24. - Engines: >=22.13.0, the strictest requirement across dependencies (ESLint needs ^22.13 || >=24). - CI matrix 22/24/26. The GitHub-action test workflows and the integration job use Node 24, like production. - Explicit least-privilege token permissions for main and the GitHub-action test workflows (CodeQL actions/missing-workflow-permissions). - Shell tests run `node` from PATH instead of process.execPath, which CodeQL traced as an uncontrolled absolute path into execFile.
Every upload attempt opened a new file stream, and a failed attempt never closed it. Besides leaking a file descriptor per retry, a stream still opening after its file was removed raised an unhandled 'error' event, which crashed the test run on Node 24. Each attempt now destroys its stream and handles its error event; read errors still fail the request that consumes the stream.
The manifest repository URL was accepted if it merely contained "https://github.com/" (CodeQL js/incomplete-url-substring-sanitization), and ".git" was removed from anywhere in the name. The URL is now parsed and must be https or git+https on github.com, and only a trailing ".git" is removed. All repository URLs of the 97 dappnode/DAppNodePackage* repos resolve to the same slug as before.
Commenting on a pull request through the issues API needs pull-requests: write; with read the build bot comment failed with 403 "Resource not accessible by integration".
|
Dappnode bot has built and pinned the built packages to an IPFS node, for commit: 7fc8437 This is a development version and should only be installed for testing purposes.
Hash: (by dappnodebot/build-action) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a set of correctness, safety and usability problems in build, publish and the GitHub actions, and modernises the toolchain. Each commit covers one theme and has regression tests. The commits are meant to be reviewed one by one.
Commits
@dappnode/toolkit, dockerode, graphql, request and rimraf.yarn auditnow reports 0 advisories.ApmRepository, whose live mainnet results match the toolkit's.lintno longer rewrites files) and Mocha 12 with tsx.yarn test:integration, run by a separate non-blocking CI job.--timeoutpredictably. Durations such as20min, and bare integer strings as seconds (the documented--timeout 5000). Numeric0means no timeout, and invalid values are rejected.execFile, so upstream tags and branch names are passed literally and can't inject shell commands. Upstream tags may contain@(n8n).--skip_saveno longer reports a successful build as an error, and--all_variantsprints the resolved variant names.delete_old_pins, which used to be ignored.docker save/xz used to be cached and uploaded as an empty archive; now it fails the build.--platform, with a fallback for Docker CLI < 28.1).--forceis given.correlationIdand wizard fields byid; an array in a variant replaces the root's.prefixUrl.--dirin GitHub actions.--dir, the variants directory and the compose file name.Behaviour changes worth a look
isBanner: "false"becomesfalse, and a warning lists every coerced value.delete_old_pinsnow actually deletes, and only replaced ancestor pins.Verification
yarn lint,yarn buildandyarn testpass (144 passing, 1 pending). The type check and tests pass at every commit; the stricter lint config from the first commit passes once the later fixes are applied.dappnode/DAppNodePackage*repos were run through validation, release-dir creation and file copy with the old and new code:notifications.yaml(isBannercoerced to a boolean); everything else differs only in formatting.docker:29-dind.api.ipfs.dappnode.ionginx vhost with Kubo v0.35.0. The old and new code upload to identical CIDs over HTTP/2. Withhttp2: falsethe original hang reproduces in every run, and the idle timeout fires only on a genuinely stalled upload.