Built-in dependency update workflow step
Goal
Elasticclaw should provide a built-in workflow step that discovers dependency manifests, updates supported dependencies using ecosystem-native tooling, produces structured output, and leaves the repository ready for later workflow steps to test, fix, and open a PR.
This step should be reusable from any workflow trigger:
- Cron workflows, such as weekly dependency maintenance
- Manual workflows, such as "run dependency updates now"
- Future event-triggered workflows, such as security alerts
Cron scheduling is covered separately in #245. This issue is specifically about the dependency update capability inside a workflow.
Product shape
Example workflow usage:
name: dependency-updates
on:
cron:
schedule: "0 9 * * 1"
timezone: "America/Chicago"
steps:
- uses: elasticclaw/dependency-updates
with:
ecosystems:
- go
- npm
grouping: all
include_major: false
separate_major: true
separate_security: true
separate_runtime: true
- run: make test
- uses: elasticclaw/open-pr
with:
title: "Update dependencies"
branch_prefix: "elasticclaw/dependency-updates"
The dependency update step should not open the PR by itself. It should update files and emit structured metadata. Later workflow steps decide how to test, fix failures, commit, and open a PR.
Supported ecosystems
Start with a narrow, useful first version:
- Go modules:
go.mod, go.sum
- Node/npm:
package.json, package-lock.json
Later versions can add:
- pnpm
- Yarn
- Ruby/Bundler
- Python requirements files
- Poetry
- uv
- Cargo
- Maven/Gradle
The step should be designed so each ecosystem implementation is isolated and testable.
Behavior
The step should:
- Discover supported manifests in the repository
- Determine the package manager and lockfile type for each manifest
- Identify available dependency updates
- Classify updates where possible:
- patch
- minor
- major
- runtime/toolchain
- security-related
- Apply selected updates according to policy
- Leave modified manifests and lockfiles in the working tree
- Emit structured output for later steps and for the workflow run summary
- Record skipped updates and the reason they were skipped
The step should prefer ecosystem-native tooling over custom version editing.
Examples:
- Go: use
go list, go get, go mod tidy, and related Go tooling
- npm: use
npm outdated, npm update, npm install, or other npm-native behavior
Configuration
Suggested options:
ecosystems:
- go
- npm
paths:
- "."
grouping: all
include_major: false
separate_major: true
separate_security: true
separate_runtime: true
allow:
- "*"
ignore:
- "example-package"
commit_message: "Update dependencies"
Defaults:
ecosystems: auto
paths:
- "."
grouping: all
include_major: false
separate_major: true
separate_security: true
separate_runtime: true
allow:
- "*"
ignore: []
PR grouping model
The default grouping should be one update set per repository per workflow run for normal patch and minor updates.
That keeps scheduled dependency maintenance quiet and useful.
The model should still support splitting updates when appropriate:
- Major updates can be skipped or emitted as a separate update group
- Security updates can be emitted separately
- Runtime/toolchain updates can be emitted separately
- Failed grouped updates can be split by ecosystem or dependency in a later workflow step
Suggested grouping values:
grouping: all | ecosystem | dependency
The dependency update step does not need to create every PR shape itself. It should produce enough structured metadata for an open-pr step or an agent instruction to create the right PR.
Structured output
The step should emit machine-readable output similar to:
{
"ecosystems": ["go", "npm"],
"manifests": [
{
"ecosystem": "go",
"path": "go.mod",
"lockfiles": ["go.sum"]
},
{
"ecosystem": "npm",
"path": "web/package.json",
"lockfiles": ["web/package-lock.json"]
}
],
"updates": [
{
"ecosystem": "go",
"name": "github.com/example/module",
"from": "v1.2.3",
"to": "v1.3.0",
"type": "minor",
"applied": true,
"group": "default"
},
{
"ecosystem": "npm",
"name": "example-package",
"from": "2.4.0",
"to": "3.0.0",
"type": "major",
"applied": false,
"skipped_reason": "major updates disabled"
}
],
"commands": [
{
"command": "go get -u ./...",
"exit_code": 0
},
{
"command": "go mod tidy",
"exit_code": 0
}
],
"files_changed": [
"go.mod",
"go.sum",
"web/package.json",
"web/package-lock.json"
]
}
This output should be available to:
- Later workflow steps
- The claw prompt/context
- The workflow run summary
- PR body generation
Failure behavior
The step should fail when dependency tooling fails in a way that prevents a reliable update.
Examples:
- Package manager is missing
- Lockfile update fails
- Manifest is malformed
- Registry request fails
- Native tooling exits non-zero
When possible, the step should preserve useful partial metadata:
- What manifests were discovered
- What command failed
- Exit code
- Relevant stderr summary
- Whether files were modified before failure
The workflow can then decide whether the claw should fix the issue, retry, split the update group, or stop.
Agent responsibilities
The built-in step should handle deterministic dependency mechanics.
The agent should handle judgment and repair work:
- Decide whether a failed update can be fixed
- Inspect changelogs or migration notes when needed
- Update code for breaking changes
- Split a failed grouped update into smaller attempts
- Write a useful PR summary
- Decide whether to skip an update with a clear reason
This keeps the updater predictable while still letting Elasticclaw use agent reasoning where it adds value.
Non-goals
- Do not make this cron-only
- Do not open PRs inside the dependency update step
- Do not hand-edit manifest versions when ecosystem tooling can do it correctly
- Do not support every package manager in the first version
- Do not create one PR per dependency by default
- Do not silently ignore failed package manager commands
First shippable version
Implement:
- Workflow step definition:
elasticclaw/dependency-updates
- Auto-discovery for Go and npm
- Basic config for
ecosystems, paths, include_major, and grouping
- Default grouped patch/minor updates
- Major updates skipped by default
- Go module updates using Go tooling
- npm updates using npm tooling
- Structured JSON output
- Files changed summary
- Clear failure output when package manager commands fail
- Tests for manifest discovery, config parsing, and output shaping
This first version should be enough for a cron workflow to run dependency updates, run tests, and open a single grouped PR.
Built-in dependency update workflow step
Goal
Elasticclaw should provide a built-in workflow step that discovers dependency manifests, updates supported dependencies using ecosystem-native tooling, produces structured output, and leaves the repository ready for later workflow steps to test, fix, and open a PR.
This step should be reusable from any workflow trigger:
Cron scheduling is covered separately in #245. This issue is specifically about the dependency update capability inside a workflow.
Product shape
Example workflow usage:
The dependency update step should not open the PR by itself. It should update files and emit structured metadata. Later workflow steps decide how to test, fix failures, commit, and open a PR.
Supported ecosystems
Start with a narrow, useful first version:
go.mod,go.sumpackage.json,package-lock.jsonLater versions can add:
The step should be designed so each ecosystem implementation is isolated and testable.
Behavior
The step should:
The step should prefer ecosystem-native tooling over custom version editing.
Examples:
go list,go get,go mod tidy, and related Go toolingnpm outdated,npm update,npm install, or other npm-native behaviorConfiguration
Suggested options:
Defaults:
PR grouping model
The default grouping should be one update set per repository per workflow run for normal patch and minor updates.
That keeps scheduled dependency maintenance quiet and useful.
The model should still support splitting updates when appropriate:
Suggested grouping values:
The dependency update step does not need to create every PR shape itself. It should produce enough structured metadata for an
open-prstep or an agent instruction to create the right PR.Structured output
The step should emit machine-readable output similar to:
{ "ecosystems": ["go", "npm"], "manifests": [ { "ecosystem": "go", "path": "go.mod", "lockfiles": ["go.sum"] }, { "ecosystem": "npm", "path": "web/package.json", "lockfiles": ["web/package-lock.json"] } ], "updates": [ { "ecosystem": "go", "name": "github.com/example/module", "from": "v1.2.3", "to": "v1.3.0", "type": "minor", "applied": true, "group": "default" }, { "ecosystem": "npm", "name": "example-package", "from": "2.4.0", "to": "3.0.0", "type": "major", "applied": false, "skipped_reason": "major updates disabled" } ], "commands": [ { "command": "go get -u ./...", "exit_code": 0 }, { "command": "go mod tidy", "exit_code": 0 } ], "files_changed": [ "go.mod", "go.sum", "web/package.json", "web/package-lock.json" ] }This output should be available to:
Failure behavior
The step should fail when dependency tooling fails in a way that prevents a reliable update.
Examples:
When possible, the step should preserve useful partial metadata:
The workflow can then decide whether the claw should fix the issue, retry, split the update group, or stop.
Agent responsibilities
The built-in step should handle deterministic dependency mechanics.
The agent should handle judgment and repair work:
This keeps the updater predictable while still letting Elasticclaw use agent reasoning where it adds value.
Non-goals
First shippable version
Implement:
elasticclaw/dependency-updatesecosystems,paths,include_major, andgroupingThis first version should be enough for a cron workflow to run dependency updates, run tests, and open a single grouped PR.