Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
28d5f54
Squashed 'pkg/helm/' content from commit f03cc04ca
ilya-lesikov Mar 24, 2026
07f2dfc
Merge commit '28d5f541b451a05b362ec8c8dee9556d34eeefc8' as 'pkg/helm'
ilya-lesikov Mar 24, 2026
961ca04
feat!: new major release 2.0
ilya-lesikov Mar 27, 2026
ebc52bf
chore: sync with main
dmmordvi Mar 31, 2026
8348f9b
refactor: remove unnecessary flags and featgates
dmmordvi Apr 1, 2026
c089430
refactor: remove unnecessary ChartDirPath
dmmordvi Apr 2, 2026
3ef6dc9
refactor: update dependency handling to support multiple operations
dmmordvi Apr 2, 2026
be2f6f8
refactor: remove deprecated dependency annotation `<name>.dependency.…
dmmordvi Apr 3, 2026
3406519
deps: replace andremueller/cobra fork with werf/3p-cobra rebased on v…
alexey-igrychev Apr 6, 2026
074d350
feat: new release history
dmmordvi Apr 7, 2026
56c19f1
refactor: rename release history --max to --revisions-limit and chang…
dmmordvi Apr 7, 2026
1a42481
feat: expose plan artifact in actions api (#586)
drey Apr 8, 2026
4c37982
Merge branch 'main' into 2
dmmordvi Apr 9, 2026
2ee2d05
chore: remove renaming step `main -> helm` from helm sync task
dmmordvi Apr 9, 2026
e2da8b7
Merge branch 'main' into 2
dmmordvi Apr 21, 2026
1e1068f
fix: use v3 util for Chart.yaml load
dmmordvi Apr 21, 2026
7a758a4
fix: clientFactory=nil breaks werf tests
dmmordvi Apr 22, 2026
e9ec2eb
doc: add plan artifact feature description (#597)
drey Apr 23, 2026
8a3cba3
chore: fix typo in the README.md (#598)
drey Apr 23, 2026
d1b6297
feat: forbid resource recreation if helm.sh/resource-policy set
drey Apr 24, 2026
3ebc015
chore: helm test cleanup and linter fixes (#609)
dmmordvi Apr 28, 2026
3e7ff15
refactor: change Version to APIVersion in ReleaseReportV3 (#607)
dmmordvi Apr 28, 2026
2159f96
feat: bump default local kube version for rendering to 1.36.0
ilya-lesikov Apr 29, 2026
55bc462
fix: simpler sorting for resources
ilya-lesikov Apr 29, 2026
3651474
fix: don't hard-fail on unsupported env vars
ilya-lesikov Apr 29, 2026
3a2264e
fix: remove support for all legacy HELM_* env vars (#611)
ilya-lesikov Apr 29, 2026
64ef060
fix: --set/set-file/set-string flags incorrectly split on commas
ilya-lesikov May 5, 2026
7f6b863
refactor: join Hooks and Resources as ResourceSpecs (#612)
dmmordvi May 5, 2026
4b380c7
refactor: use `encoding/json` for marshaling and unmarshaling (#613)
dmmordvi May 7, 2026
d0b1f53
feat: add DockerConfig flag (#605)
dmmordvi May 12, 2026
73d4a88
feat: improve runtime annotations and labels handling (#615)
drey May 13, 2026
a8c983f
feat: fail on invalid annotations or labels (#614)
drey May 13, 2026
ec40944
feat: allow to disable values schema validation (#616)
drey May 13, 2026
46e98e9
fix: pass NoPodLogs to kubedog (#621)
drey May 15, 2026
4a0b1e8
feat: set default delete propagation policy to backgound (#623)
drey May 18, 2026
581acf9
feat: support external dependencies for deploy-dependency and delete-…
dmmordvi May 18, 2026
438a1e2
fix: add SetupColorLevel function for enhanced logging color configur…
dmmordvi May 18, 2026
18ad551
feat: use transformers and patchers on rollback (#624)
drey May 25, 2026
8528a0a
feat: remove deprecated external dependencies annotations (#625)
dmmordvi May 26, 2026
adf8a42
feat: case insensitive group/version/kind for `deploy/delete-dependen…
dmmordvi May 26, 2026
74d3ea4
fix: correct fork:helm:sync task
drey May 27, 2026
ea85faf
feat: upgrade to helm v4.2.0 (#627)
drey Jun 4, 2026
ae98e04
feat: native Chart v3 and Release v2 support
drey Jun 10, 2026
8f935db
refactor: refactor chart v3 and release v2 support
ilya-lesikov Jun 16, 2026
ec0af5b
feat: move repo commands from root to chart repo (#640)
dmmordvi Jun 17, 2026
c22d5fd
docs: enhance README with external dependency handling details for an…
dmmordvi Jun 17, 2026
89f4783
chore: add method to update release storage labels
ilya-lesikov Jul 8, 2026
4acd290
chore: reformat
ilya-lesikov Jul 8, 2026
e2780d5
Merge branch 'main' into 2
dmmordvi Jul 9, 2026
d414ee7
fix: resolve issues after conflicts
dmmordvi Jul 9, 2026
ee64bf7
chore: bump kubedog
dmmordvi Jul 9, 2026
9241ea8
feat: add --diff-patches and patches.yaml support
ilya-lesikov Jul 10, 2026
deda7bc
chore: fix tests
ilya-lesikov Jul 14, 2026
5c9ccec
chore: remove leaked test files
ilya-lesikov Jul 14, 2026
8f85359
fix: cleanup TODOs for major (#663)
ilya-lesikov Jul 21, 2026
fec1159
fix: register go-client auth plugins (#670)
drey Jul 27, 2026
0d2b4e0
feat: port --lookup-resources and --no-create-namespace from main (#671)
alexey-igrychev Jul 28, 2026
f6ce79b
feat: embed kubeconform validation schemas into the binary (#673)
drey Jul 31, 2026
2a29517
fix: repair ai lookup tests after helm fork api changes (#676)
drey Jul 31, 2026
cb96a15
feat: embed deno binary into release binaries behind embeddeno tag
dmmordvi Jul 30, 2026
bee47f9
refactor: pass embedded Deno by context through TypeScriptOptions
dmmordvi Jul 31, 2026
615df53
feat: enhance Deno embedding process and sync platform lists
dmmordvi Jul 31, 2026
62d593f
fix: harden deno embedding per review findings
dmmordvi Jul 31, 2026
ee84ed7
fix: format taskfile
dmmordvi Jul 31, 2026
3abafee
fix: remove unsupported os/arch from getDownloadLink
dmmordvi Jul 31, 2026
9b5af8d
fix: restore DENO_EMBED_ROOT for werf
dmmordvi Jul 31, 2026
4c91c3a
fix: pin deno digests in the repository instead of fetching them
dmmordvi Jul 31, 2026
bd6de22
refactor: move embed-deno to scripts and drop the redundant sha option
dmmordvi Jul 31, 2026
0ed2a27
refactor: clear comments
dmmordvi Aug 1, 2026
55abe9f
chore: add comment about unsupported platform
dmmordvi Aug 1, 2026
fa56ffe
refactor: use restify instead of http for denolock client
dmmordvi Aug 1, 2026
0b9d576
chore: bump deno version and update deno lock
dmmordvi Aug 1, 2026
45823a4
chore: add check_deno_lock_upstream job to CI workflow
dmmordvi Aug 1, 2026
8b91b6d
docs: update deno lock version in README.md
dmmordvi Aug 1, 2026
79ce86a
fix: ignore helm.sh(werf.io)/resource-policy: keep from cluster
ilya-lesikov Aug 4, 2026
e9bbd6e
feat: clean null fields in rendered manifests by default for better c…
ilya-lesikov Aug 4, 2026
1c5d25e
fix: injected service values might break values.schema.json
ilya-lesikov Aug 4, 2026
9d04918
fix: optimize validation args
drey Aug 5, 2026
26aa17e
Merge branch 'main' into 2
ilya-lesikov Aug 6, 2026
b4771c6
fix: exclude external dependencies from readiness forcing
ilya-lesikov Aug 6, 2026
5647588
feat: add case-insensitive-condition-tracking feature gate
ilya-lesikov Aug 6, 2026
ec98995
fix(helm): serialize action configuration initialization (#686)
alexey-igrychev Aug 7, 2026
9d7f0cb
Merge remote-tracking branch 'origin/2' into 2
ilya-lesikov Aug 7, 2026
91104e4
chore: format
ilya-lesikov Aug 7, 2026
f5a2103
chore: bump kubedog
ilya-lesikov Aug 7, 2026
6f46733
fix: prevent concurrent Helm configuration races (#688)
alexey-igrychev Aug 7, 2026
0585a1f
feat: always track resource conditions case-insensitively
ilya-lesikov Aug 7, 2026
72d7f3d
chore: bump kubedog
ilya-lesikov Aug 9, 2026
0609686
fix: prevent progress printer race (#690)
alexey-igrychev Aug 10, 2026
8ed2393
chore: add AGENTS.md symlink for claude (#694)
dmmordvi Aug 20, 2026
191171c
feat: add `renderPatches` support for --patches/patches.yaml (#696)
dmmordvi Aug 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
44 changes: 44 additions & 0 deletions .github/workflows/_check_deno_lock_upstream.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: xxxxx(internal)

on:
workflow_call:
inputs:
forceSkip:
default: false
type: string

defaults:
run:
shell: bash

env:
DEBIAN_FRONTEND: "noninteractive"

jobs:
_:
if: inputs.forceSkip == 'false'
runs-on: ubuntu-22.04
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Set up Go
uses: actions/setup-go@v6
with:
cache: false
go-version-file: go.mod

- name: Install Task
uses: go-task/setup-task@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}

# Fails when the release assets the lock pins no longer hash to what it records: GitHub lets an
# asset be replaced without moving its tag, and nothing else would notice, since builds verify
# against the committed lock and never look upstream. A newer Deno release is only reported,
# since bumping the pin is a decision.
- name: Check the pinned Deno release against upstream
run: task -p check:deno-lock-upstream
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43 changes: 43 additions & 0 deletions .github/workflows/_check_validation_schemas_upstream.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: xxxxx(internal)

on:
workflow_call:
inputs:
forceSkip:
default: false
type: string

defaults:
run:
shell: bash

env:
DEBIAN_FRONTEND: "noninteractive"

jobs:
_:
if: inputs.forceSkip == 'false'
runs-on: ubuntu-22.04
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Set up Go
uses: actions/setup-go@v6
with:
cache: false
go-version-file: go.mod

- name: Install Task
uses: go-task/setup-task@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}

# Fails when upstream changed schemas the committed archives were generated from, which is the
# only signal that "task generate:validation-schemas:force" is due: the generator itself never
# goes looking, so that builds stay offline and reproducible.
- name: Check embedded validation schemas against upstream
run: task -p check:validation-schemas-upstream
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8 changes: 8 additions & 0 deletions .github/workflows/test_daily.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ jobs:
lint:
uses: ./.github/workflows/_lint.yml

check_validation_schemas_upstream:
uses: ./.github/workflows/_check_validation_schemas_upstream.yml

check_deno_lock_upstream:
uses: ./.github/workflows/_check_deno_lock_upstream.yml

unit:
uses: ./.github/workflows/_test_unit.yml
with:
Expand All @@ -26,6 +32,8 @@ jobs:
if: always()
needs:
- lint
- check_validation_schemas_upstream
- check_deno_lock_upstream
- coverage_report
uses: werf/common-ci/.github/workflows/notification.yml@main
secrets:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/test_pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ jobs:
- 'go.mod'
- 'go.sum'
- 'cmd/nelm/**'
- 'internal/**'
- 'pkg/**'
- 'scripts/**'
lint:
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
*.swp
*.test
.task
/.idea/
/.vscode/
/Taskfile.yaml
Expand All @@ -9,5 +10,10 @@
/go.work
/go.work.sum
node_modules/
/pkg/ts/embed/*/*/deno.gz
/pkg/ts/embed/*/*/deno.gz.*.tmp
/.opencode/
/.sisyphus

# Regenerated by TestDependencyBuildCmdWithHelmV2Hash on every run (fresh mtimes)
/pkg/helm/pkg/cmd/testdata/testcharts/issue-7233/charts/alpine-0.1.0.tgz
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

All rules in this document are requirements — not suggestions. ALWAYS follow them.

Nelm is a Go-based Kubernetes deployment tool, which deploys Helm charts, is compatible with Helm releases, and is an alternative to Helm. Nelm also used as the deployment engine of [werf](https://github.com/werf/werf).
Nelm is a Go-based Kubernetes deployment tool, which deploys Helm charts, is compatible with Helm releases, and is an alternative to Helm. Nelm is built on top of a Helm fork and is also used as the deployment engine of [werf](https://github.com/werf/werf).

## Highest-priority rule (MANDATORY)

Expand Down Expand Up @@ -75,7 +75,7 @@ ALWAYS use these `task` commands. NEVER use raw `go build`, `go test`, `go fmt`,
- ALWAYS place tests alongside source files, not in a separate directory.
- Test helpers go in `helpers_test.go` (or `helpers_ai_test.go` for AI-written helpers).
- Test fixtures go in `testdata/` subdirectory next to the tests.
- Shared test helpers are in `internal/test/`.
- Shared test helpers are in `pkg/test/`.

## PR review guidelines (MANDATORY)

Expand All @@ -85,6 +85,6 @@ ALWAYS use these `task` commands. NEVER use raw `go build`, `go test`, `go fmt`,

## Related repositories

- [werf/kubedog](https://github.com/werf/kubedog) — Kubernetes resource tracking library. Used by `internal/track/`.
- [werf/kubedog](https://github.com/werf/kubedog) — Kubernetes resource tracking library. Used by `pkg/track/`.
- [werf/common-go](https://github.com/werf/common-go) — Shared Go libraries (secrets, CLI utilities, locking).
- [werf/werf](https://github.com/werf/werf) — CI/CD tool that uses nelm as its deployment engine.
1 change: 1 addition & 0 deletions CLAUDE.md
68 changes: 17 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ Nelm is production-ready: as the werf deployment engine, it was battle-tested ac
- [`werf.io/weight` annotation](#werfioweight-annotation)
- [`werf.io/deploy-dependency-<id>` annotation](#werfiodeploy-dependency-id-annotation)
- [`werf.io/delete-dependency-<id>` annotation](#werfiodelete-dependency-id-annotation)
- [`<id>.external-dependency.werf.io/resource` annotation](#idexternal-dependencywerfioresource-annotation)
- [`<id>.external-dependency.werf.io/name` annotation](#idexternal-dependencywerfioname-annotation)
- [`werf.io/ownership` annotation](#werfioownership-annotation)
- [`werf.io/deploy-on` annotation](#werfiodeploy-on-annotation)
- [`werf.io/delete-policy` annotation](#werfiodelete-policy-annotation)
Expand Down Expand Up @@ -87,7 +85,6 @@ Nelm is production-ready: as the werf deployment engine, it was battle-tested ac
- [`NELM_FEAT_NATIVE_RELEASE_UNINSTALL` environment variable](#nelm_feat_native_release_uninstall-environment-variable)
- [`NELM_FEAT_PERIODIC_STACK_TRACES` environment variable](#nelm_feat_periodic_stack_traces-environment-variable)
- [`NELM_FEAT_FIELD_SENSITIVE` environment variable](#nelm_feat_field_sensitive-environment-variable)
- [`NELM_FEAT_CLEAN_NULL_FIELDS` environment variable](#nelm_feat_clean_null_fields-environment-variable)
- [`NELM_FEAT_MORE_DETAILED_EXIT_CODE_FOR_PLAN` environment variable](#nelm_feat_more_detailed_exit_code_for_plan-environment-variable)
- [More documentation](#more-documentation)
- [Limitations](#limitations)
Expand Down Expand Up @@ -182,11 +179,11 @@ Dependency commands:
chart dependency update Update Chart.lock and download chart dependencies.

Repo commands:
repo add Set up a new chart repository.
repo remove Remove a chart repository.
repo update Update info about available charts for all chart repositories.
repo login Log in to an OCI registry with charts.
repo logout Log out from an OCI registry with charts.
chart repo add Set up a new chart repository.
chart repo remove Remove a chart repository.
chart repo update Update info about available charts for all chart repositories.
chart repo login Log in to an OCI registry with charts.
chart repo logout Log out from an OCI registry with charts.

Other commands:
completion bash Generate the autocompletion script for bash
Expand Down Expand Up @@ -223,8 +220,8 @@ Generally, the migration from Helm to Nelm should be as simple as changing Helm

The resource deployment subsystem of Helm is rewritten from scratch in Nelm. During the deployment, Nelm builds the Directed Acyclic Graph (DAG) of all operations we want to perform in the cluster to do the release, then the DAG is executed. The DAG allowed us to implement advanced resource ordering capabilities, such as:
* The `werf.io/weight` annotation: similar to `helm.sh/hook-weight`, but also works for non-hook resources. Resources with the same weight deployed in parallel.
* The `werf.io/deploy-dependency-<id>` annotation: do not deploy the annotated resource until the dependency is present or ready. This is the most powerful and effective way to enforce deployment order in Nelm.
* The `<id>.external-dependency.werf.io/resource` annotation: do not deploy the annotated resource until the dependency is ready. The dependency can be an external, non-release resource, e.g. a resource created by a third-party operator.
* The `werf.io/deploy-dependency-<id>` annotation: do not deploy the annotated resource until the dependency is present or ready. Works for both release resources and external cluster resources (e.g. resources created by a third-party operator). This is the most powerful and effective way to enforce deployment order in Nelm.
* The `werf.io/delete-dependency-<id>` annotation: do not delete the annotated resource until the dependency is absent. Works for both release resources and external cluster resources.
* Helm Hooks and their weights are supported, too.

![ordering](resources/images/graph.png)
Expand Down Expand Up @@ -373,58 +370,39 @@ Default:

### `werf.io/deploy-dependency-<id>` annotation

The resource will deploy only after all of its dependencies are satisfied. It waits until the specified resource is just `present` or is also `ready`. It serves as a more powerful alternative to hooks and `werf.io/weight`. You can only point to resources in the release. This annotation has higher priority than `werf.io/weight` and `helm.sh/hook-weight`. This annotation has no effect if the resource on which we depend upon is outside the stage (pre, main, post, ...) of the resource with the annotation.
The resource will deploy only after all of its dependencies are satisfied. It waits until the specified resource is just `present` or is also `ready`. It serves as a more powerful alternative to hooks and `werf.io/weight`. This annotation has higher priority than `werf.io/weight` and `helm.sh/hook-weight`. This annotation has no effect on internal (release) dependencies if the resource on which we depend upon is outside the stage (pre, main, post, ...) of the resource with the annotation.

If `external=true` or `external=auto` and the dependency is not found in the release, then the dependency is treated as external to the release: `name`, `kind` and `version` must be specified.

Example:
```yaml
werf.io/deploy-dependency-db: state=ready,kind=StatefulSet,name=postgres
werf.io/deploy-dependency-app: state=present,kind=Deployment,group=apps,version=v1,name=app,namespace=app
werf.io/deploy-dependency-secret: state=ready,kind=Secret,version=v1,name=my-vault-secret,external=true
```
Format:
```
werf.io/deploy-dependency-<anything>: state=ready|present[,name=<name>][,namespace=<namespace>][,kind=<kind>][,group=<group>][,version=<version>]
werf.io/deploy-dependency-<anything>: state=ready|present[,name=<name>][,namespace=<namespace>][,kind=<kind>][,group=<group>][,version=<version>][,external=auto|true|false]
```

### `werf.io/delete-dependency-<id>` annotation

The resource will be deleted only after all of its dependencies are satisfied. It waits until the specified resource is `absent`. You can only point to resources in the release. This annotation has no effect if the resource on which we depend upon is outside the stage (pre, main, post, ...) of the resource with the annotation.
The resource will be deleted only after all of its dependencies are satisfied. It waits until the specified resource is `absent`. This annotation has no effect on internal (release) dependencies if the resource on which we depend upon is outside the stage (pre, main, post, ...) of the resource with the annotation.

If `external=true` or `external=auto` and the dependency is not found in the release, then the dependency is treated as external to the release: `name`, `kind` and `version` must be specified.

Example:
```yaml
werf.io/delete-dependency-db: state=absent,kind=StatefulSet,name=postgres
werf.io/delete-dependency-app: state=absent,kind=Deployment,group=apps,version=v1,name=app,namespace=app
werf.io/delete-dependency-secret: state=absent,kind=Secret,version=v1,name=my-vault-secret,external=true
```
Format:
```
werf.io/delete-dependency-<anything>: state=absent[,name=<name>][,namespace=<namespace>][,kind=<kind>][,group=<group>][,version=<version>]
```

### `<id>.external-dependency.werf.io/resource` annotation

The resource will deploy only after all of its external dependencies are satisfied. It waits until the specified resource is `present` and `ready`. You can only point to resources outside the release.

Example:
```yaml
secret.external-dependency.werf.io/resource: secret/config
someapp.external-dependency.werf.io/resource: deployments.v1.apps/app
```
Format:
```
<anything>.external-dependency.werf.io/resource: <kind>[.<version>.<group>]/<name>
werf.io/delete-dependency-<anything>: state=absent[,name=<name>][,namespace=<namespace>][,kind=<kind>][,group=<group>][,version=<version>][,external=auto|true|false]
```

### `<id>.external-dependency.werf.io/name` annotation

Set the namespace of the external dependency defined by `<id>.external-dependency.werf.io/resource`. `<id>` must match on both annotations. If not specified, the release namespace is used.

Example:
```yaml
someapp.external-dependency.werf.io/name: someapp-production
```
Format:
```
<anything>.external-dependency.werf.io/name: <name>
```

### `werf.io/ownership` annotation

Expand Down Expand Up @@ -866,18 +844,6 @@ export NELM_FEAT_FIELD_SENSITIVE=true
nelm release plan install -n myproject -r myproject
```

### `NELM_FEAT_CLEAN_NULL_FIELDS` environment variable

Improve Helm chart compatibility. When rendering charts, remove keys with `null` values from the rendered resource manifests, before applying them. Otherwise, SSA often fail on `null` values, which didn't happen with 3WM.

Will be the default in the next major release.

Example:
```shell
export NELM_FEAT_CLEAN_NULL_FIELDS=true
nelm release install -n myproject -r myproject
```

### `NELM_FEAT_MORE_DETAILED_EXIT_CODE_FOR_PLAN` environment variable

When the `--exit-code` flag is specified for `nelm release plan install`, return exit code 3, if no resource changes planned, but release still must be installed. Previously, exit code 2 was returned in this case.
Expand Down
Loading