Maintaining Wrapper Packages
This guide covers the day-to-day workflows for maintaining a datamitsu wrapper package — keeping tool versions current, verifying integrity across platforms, and automating updates.
Overview
A wrapper package is a datamitsu configuration that bundles a curated set of tools for a specific use case (e.g., a company's standard linting stack). As a wrapper maintainer, your responsibilities include:
- Updating tool versions when new releases are published
- Regenerating lock files for reproducible installs
- Verifying SHA-256 hashes across all supported platforms
- Testing that updated tools work correctly
datamitsu provides devtools commands to automate these tasks.
Updating Tool Versions
Binary Apps: devtools pull-github
Binary apps are downloaded directly from GitHub releases. Use pull-github to fetch the latest release versions and compute hashes automatically.
Apply updates:
datamitsu devtools pull-github apps/githubApps.json --update
With --update, the command fetches the latest release tags, downloads binaries for all platform tuples (Darwin/Linux/Windows/FreeBSD/OpenBSD on amd64/arm64, Linux with glibc/musl), computes SHA-256 hashes, fetches the repository description from GitHub API, and writes the results back to the JSON file.
Verify binary extraction after update:
datamitsu devtools pull-github apps/githubApps.json --update --verify-extraction
The --verify-extraction flag additionally downloads each binary and verifies it can be extracted correctly. This catches issues like changed archive structures or renamed binaries inside archives.
:::note Releases with mixed asset types
Some tools publish VS Code extensions (.vsix), Linux packages (.deb, .rpm), NuGet packages (.nupkg), Python wheels (.whl), Windows installers (.msi), or macOS installer packages (.pkg) alongside binary archives in the same GitHub release. datamitsu automatically excludes these non-executable formats before scoring, so only actual binaries compete for selection. No configuration is needed — the filtering is automatic.
:::
Node Apps (npm): devtools pull-node
Node apps are npm packages managed via pnpm. Use pull-node to check for updates on the npm registry.
Preview available updates:
datamitsu devtools pull-node apps/nodeApps.json --update --dry-run
The --update --dry-run combination fetches the latest versions and shows what would change without writing to the file.
Apply updates:
datamitsu devtools pull-node apps/nodeApps.json --update
This queries the npm registry for each configured package, compares versions, and updates the JSON file with new versions and descriptions.
Regenerate lock files after updating:
After updating node app versions, regenerate their lock files to ensure reproducible installs:
datamitsu config lockfile prettier
datamitsu config lockfile eslint
Each command outputs brotli-compressed lock file content (with a br: prefix) that you paste into the app's lockFile field in your configuration.
UV Apps (Python): devtools pull-uv
UV apps are Python packages installed in isolated environments. Use pull-uv to check for updates on PyPI.
Preview available updates:
datamitsu devtools pull-uv apps/uvApps.json --update --dry-run
Apply updates:
datamitsu devtools pull-uv apps/uvApps.json --update
This queries PyPI for each configured package, compares versions, and updates the JSON file.
Regenerate lock files after updating:
datamitsu config lockfile yamllint
Runtimes: devtools pull-runtimes
Runtimes (Node.js, UV/Python, JVM/Temurin) need periodic updates too. Use pull-runtimes to fetch the latest runtime versions.
Update all runtimes:
datamitsu devtools pull-runtimes runtimes/runtimes.json --update
The --update flag is required as a safety guard — the command refuses to run without it.
Update a specific runtime only:
datamitsu devtools pull-runtimes runtimes/runtimes.json --update --runtime node
datamitsu devtools pull-runtimes runtimes/runtimes.json --update --runtime uv
datamitsu devtools pull-runtimes runtimes/runtimes.json --update --runtime jvm
Preview changes without writing:
datamitsu devtools pull-runtimes runtimes/runtimes.json --update --dry-run
The command fetches versions from upstream sources:
- Node.js: latest LTS version from endoflife.date API
- PNPM: latest version from npm registry
- Python: latest stable (non-EOL) version from endoflife.date API
- Java (Temurin): latest major version from Adoptium API
It then downloads runtime binaries for all platform tuples, computes SHA-256 hashes, and deduplicates musl entries that are identical to glibc.
Bumping the Node.js runtime
The Node.js runtime is a direct, hash-pinned archive (like the JVM runtime), so bumping it means refreshing the pinned version and the per-platform hashes in runtimes.json:
datamitsu devtools pull-runtimes runtimes/runtimes.json --update --runtime node
This resolves the latest Node.js LTS, builds the archive URLs for every os/arch/libc combination, and records a SHA-256 hash for each:
- glibc, macOS, and Windows hashes are taken from nodejs.org's clearsigned
SHASUMS256.txt.ascand GPG-verified against the embedded official Node.js release public keys. An invalid or untrusted signature aborts the pull, giving a strong supply-chain anchor. - musl hashes come from unofficial-builds.nodejs.org's unsigned
SHASUMS256.txt(Node publishes no signature for musl builds) and are pinned in git — the same trust model as the officialnode:alpineimage.
After a Node.js or pnpm version bump, regenerate the lock files for your node apps so they resolve against the new runtime, then commit the refreshed runtimes.json:
datamitsu config lockfile eslint
datamitsu config lockfile prettier
Bumping the Go runtime
datamitsu devtools pull-runtimes runtimes.json --update --runtime go
The Go SDK archives and their per-file SHA-256 come from go.dev (https://go.dev/dl/?mode=json): HTTPS plus published SHA-256, no GPG — the same trust posture as the musl Node path. The pull preserves (or sets) go.goVersion in the runtime entry.
Testing After Updates
Verify cross-platform integrity
After updating any tool or runtime versions, run verify-all to check integrity across all platforms:
datamitsu devtools verify-all
This command:
- Downloads and hash-verifies all binary apps for every configured platform
- Downloads and hash-verifies all managed runtime binaries
- Installs runtime-managed apps (node, UV, JVM) on the current platform
- Runs version checks to confirm tools execute correctly
Useful flags:
# Skip version checks (faster, hash-only verification)
datamitsu devtools verify-all --no-version-check
# Increase download concurrency
datamitsu devtools verify-all --concurrency 8
# Skip entries that passed on the last run with unchanged config
datamitsu devtools verify-all --skip-passed
# Machine-readable output for CI pipelines
datamitsu devtools verify-all --json
# Skip remote config resolution
datamitsu devtools verify-all --no-remote
Results are cached incrementally in a state file. Using --skip-passed skips entries whose configuration fingerprint hasn't changed since the last successful verification, which speeds up repeated runs during development.
Local smoke test
Always test locally before publishing:
# Re-download everything
datamitsu init
# Run the full check pipeline
datamitsu check
# Verify specific tools
datamitsu exec prettier -- --version
datamitsu exec eslint -- --version
Automation
GitHub Actions: periodic version checks
Set up automated version checking with a scheduled GitHub Actions workflow:
name: Check for tool updates
on:
schedule:
- cron: "0 9 * * 1" # Every Monday at 9:00 UTC
workflow_dispatch: # Allow manual triggers
jobs:
check-updates:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup datamitsu
run: |
# Install datamitsu (adjust for your setup)
go build -o datamitsu .
# Note: pull-github does not support --dry-run.
# Use pull-github --update in the automated update PR workflow instead.
- name: Check node app updates
run: ./datamitsu devtools pull-node apps/nodeApps.json --update --dry-run
- name: Check UV app updates
run: ./datamitsu devtools pull-uv apps/uvApps.json --update --dry-run
- name: Check runtime updates
run: ./datamitsu devtools pull-runtimes runtimes/runtimes.json --update --dry-run
GitHub Actions: automated update PR
For a more hands-off workflow, create a workflow that applies updates and opens a pull request:
name: Update tool versions
on:
schedule:
- cron: "0 9 1 * *" # First day of each month
workflow_dispatch:
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup datamitsu
run: go build -o datamitsu .
- name: Update binary apps
run: ./datamitsu devtools pull-github apps/githubApps.json --update
- name: Update node apps
run: ./datamitsu devtools pull-node apps/nodeApps.json --update
- name: Update UV apps
run: ./datamitsu devtools pull-uv apps/uvApps.json --update
- name: Update runtimes
run: ./datamitsu devtools pull-runtimes runtimes/runtimes.json --update
- name: Verify all platforms
run: ./datamitsu devtools verify-all
- name: Create pull request
uses: peter-evans/create-pull-request@v6
with:
title: "chore: update tool versions"
body: "Automated tool version update. Review changes and verify locally before merging."
branch: chore/update-tool-versions
commit-message: "chore: update tool versions"
Best Practices
Semantic versioning
Follow semantic versioning for your wrapper package releases:
- Patch (1.0.x): tool version bumps with no configuration changes
- Minor (1.x.0): new tools added, new features in configuration
- Major (x.0.0): tools removed, breaking configuration changes, minimum version bumps
Changelog
Keep a changelog documenting what changed in each release:
- Which tools were updated and to what version
- Any new tools added or removed
- Configuration changes that users need to be aware of
- Minimum datamitsu version changes (
getMinVersion())
Update workflow
A typical update cycle looks like this:
- Run
devtools pull-*commands to detect and apply updates - Regenerate lock files for any updated node/UV apps
- Run
devtools verify-allto check cross-platform integrity - Run
datamitsu init && datamitsu checklocally - Commit, push, and create a release
Migration guides
When making breaking changes (removing tools, changing configuration structure), provide a migration guide in your release notes explaining:
- What changed and why
- Step-by-step instructions to update
- The new minimum datamitsu version if changed
Configuring pnpm Settings for Node Apps
Node apps run pnpm install in an isolated directory managed by datamitsu. datamitsu always writes a pnpm-workspace.yaml containing secure supply chain defaults before pnpm install runs. You can override or extend those defaults by supplying your own pnpm-workspace.yaml via App.files — datamitsu shallow-merges your keys on top of the baseline.
See the Supply Chain Security guide for the full list of baseline settings and what each one does.
:::caution Files are written only on initial install
App.files (including pnpm-workspace.yaml) are read on every install, but the install directory is only rebuilt when the app's config hash changes. If you change files after an app is already cached, run datamitsu store clear (or delete the app's subdirectory under .apps/node/) to force a reinstall.
:::
Apps without build scripts (zero config)
No App.files["pnpm-workspace.yaml"] is required. datamitsu writes the secure defaults automatically:
const eslint = {
node: {
packageName: "eslint",
binPath: "node_modules/.bin/eslint",
version: "9.17.0",
lockFile: "br:...",
},
};
Apps that need build scripts (puppeteer, sharp, esbuild, etc.)
pnpm 11 blocks lifecycle scripts by default. If install fails with ERR_PNPM_IGNORED_BUILDS, allowlist the package via allowBuilds:
const mmdc = {
files: {
"pnpm-workspace.yaml": YAML.stringify({
allowBuilds: { puppeteer: true },
}),
},
node: {
packageName: "@mermaid-js/mermaid-cli",
binPath: "node_modules/.bin/mmdc",
version: "11.15.0",
lockFile: "br:...",
},
};
The merged result written to the app environment keeps all secure defaults (strictDepBuilds: true, minimumReleaseAge: 10080, etc.) plus the user's allowBuilds entry. Only the keys you explicitly set are overridden.
After adding allowBuilds, regenerate the lock file so pnpm can record the approved builds:
pnpm exec datamitsu config lockfile mmdc
Overriding a security key
User intent wins on every key. Setting strictDepBuilds: false disables strict build approval — use only when you understand the risk:
files: {
"pnpm-workspace.yaml": YAML.stringify({
strictDepBuilds: false,
}),
}
:::note Node and UV apps
For node apps, any package.json included in App.files will be overwritten by the datamitsu core when it writes the managed package.json. Use pnpm-workspace.yaml for customization — the core merges that file with secure defaults rather than overwriting it.
For UV apps, project-level settings are configured via pyproject.toml. However, any pyproject.toml included in App.files will be overwritten by the datamitsu core when it writes the managed pyproject.toml. This customization path is not available for UV apps.
:::