Skip to content

Commit 9a9993b

Browse files
committed
Merge commit '967e72da6df226619f0a9b1c7b3e1d0992e9ba1c' into renovate/configure
2 parents 00daf9e + 967e72d commit 9a9993b

107 files changed

Lines changed: 9154 additions & 3404 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test.yml

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
name: Test
2-
32
on:
43
pull_request:
54
types: [opened]
65
push:
7-
branches-ignore: [ main ]
8-
6+
branches-ignore: [main]
97
env:
10-
GO_VERSION: '1.24'
11-
GOLANGCI_LINT_VERSION: 'v2.1'
12-
8+
GO_VERSION: '1.26.1'
9+
GOLANGCI_LINT_VERSION: 'v2.11.4'
1310
jobs:
1411
# Check if there is any dirty change for go mod tidy
1512
go-mod:
@@ -24,7 +21,6 @@ jobs:
2421
go mod tidy
2522
git diff --exit-code go.mod
2623
git diff --exit-code go.sum
27-
2824
go-test:
2925
needs: go-mod
3026
runs-on: ubuntu-latest
@@ -34,7 +30,6 @@ jobs:
3430
with:
3531
go-version: ${{ env.GO_VERSION }}
3632
- run: go test ./... -race
37-
3833
golangci-lint:
3934
needs: go-test
4035
runs-on: ubuntu-latest
@@ -46,7 +41,6 @@ jobs:
4641
- uses: golangci/golangci-lint-action@v8
4742
with:
4843
version: ${{ env.GOLANGCI_LINT_VERSION }}
49-
5044
detect-modules: # ref: https://github.com/golangci/golangci-lint-action/tree/main
5145
needs: [golangci-lint, go-test, go-mod]
5246
runs-on: ubuntu-latest
@@ -65,8 +59,7 @@ jobs:
6559
name: go_work
6660
path: go.work
6761
- id: set-modules
68-
run: echo "modules=$(go list -m -json | jq -s '.' | jq -c '[.[].Dir]')" >> $GITHUB_OUTPUT
69-
62+
run: echo "modules=$(go work edit -json | jq -c '[.Use[].DiskPath]')" >> $GITHUB_OUTPUT
7063
go-mod-examples:
7164
needs: [detect-modules]
7265
runs-on: ubuntu-latest
@@ -86,7 +79,6 @@ jobs:
8679
git diff --exit-code go.mod
8780
git diff --exit-code go.sum
8881
working-directory: ${{ matrix.modules }}
89-
9082
go-test-examples:
9183
needs: [detect-modules, go-mod-examples]
9284
runs-on: ubuntu-latest
@@ -105,7 +97,6 @@ jobs:
10597
name: go_work
10698
- run: go test ./...
10799
working-directory: ${{ matrix.modules }}
108-
109100
golangci-lint-examples:
110101
needs: [detect-modules, go-test-examples]
111102
runs-on: ubuntu-latest

.golangci.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,20 @@ linters:
6767
checks:
6868
- all
6969
- '-QF1008' # not need to fix; we understand how to call nested structs
70+
revive:
71+
rules:
72+
- name: var-naming # waiting for package name will be fixed (incorrect naming)
73+
severity: warning
74+
disabled: false
75+
exclude: [""]
76+
arguments:
77+
- ["ID"] # AllowList
78+
- ["VM"] # DenyList
79+
- - skip-initialism-name-checks: false
80+
upper-case-const: false
81+
skip-package-name-checks: true
82+
skip-package-name-collision-with-go-std: false
83+
extra-bad-package-names: []
7084
exclusions:
7185
generated: lax
7286
presets:

Makefile

Lines changed: 96 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,8 @@
1-
GO=$(shell which go)
2-
GIT=$(shell which git)
3-
GOLANGCI_LINT=$(shell which golangci-lint)
4-
5-
.PHONY: go-check
6-
go-check:
7-
$(call error-if-empty,$(GO),go)
8-
9-
.PHONY: git-check
10-
git-check:
11-
$(call error-if-empty,$(GIT),git)
12-
13-
.PHONY: golangci-lint-check
14-
golangci-lint-check:
15-
$(call error-if-empty,$(GIT),git)
161

172
.PHONY: go-module-version
183
go-module-version: go-check git-check
194
@echo "go get $(shell $(GO) list ./pkg/app)@$(shell $(GIT) rev-parse HEAD)"
205

21-
.PHONY: test
22-
test: go-check
23-
@$(GO) test --race --cover ./...
24-
25-
.PHONY: lint
26-
lint: golangci-lint-check
27-
@$(GOLANGCI_LINT) run ./... --fix
28-
296
.PHONY: examples
307
examples: go-check examples-mod examples-test examples-lint
318
@echo "Running examples tests and linting"
@@ -46,12 +23,106 @@ examples-test: go-check
4623
done
4724

4825
.PHONY: examples-lint
49-
examples-lint: golangci-lint-check
26+
examples-lint: golangci-lint
5027
@for dir in $$(find . -mindepth 2 -name go.mod | sed -r 's/(.*)(go.mod)/\1/g'); do \
5128
echo "Running linter in $${dir}"; \
5229
cd $(CURDIR)/$${dir} && $(GOLANGCI_LINT) run ./... --fix && cd $(CURDIR); \
5330
done
5431

32+
.PHONY: lint
33+
lint: golangci-lint ## Run linter.
34+
@$(GOLANGCI_LINT) run --fix
35+
36+
.PHONY: test
37+
test: go-check
38+
@$(GO) test --race --cover ./...
39+
40+
## Run all generate-* jobs in bulk.
41+
.PHONY: generate
42+
generate: update-workflows-go-version update-workflows-golangci-lint-version
43+
44+
45+
##@ Dependencies
46+
47+
WHOAMI ?= $(shell whoami)
48+
49+
## Location to install dependencies to
50+
LOCALBIN ?= $(shell pwd)/bin
51+
$(LOCALBIN):
52+
mkdir -p $(LOCALBIN)
53+
54+
## Tool Binaries
55+
GO=$(shell which go)
56+
GIT=$(shell which git)
57+
GOLANGCI_LINT = $(LOCALBIN)/golangci-lint
58+
YQ = $(LOCALBIN)/yq
59+
60+
## TODO: remap in yaml file (version.yaml or smthng)
61+
## Tool Versions
62+
# GO_BUILDER_VERSION must be without 'v' prefix
63+
GO_BUILDER_VERSION = 1.26.1
64+
GOLANGCI_LINT_VERSION = v2.11.4
65+
YQ_VERSION ?= v4.50.1
66+
67+
68+
.PHONY: update-workflows-go-version
69+
update-workflows-go-version: yq
70+
for file in $$(find .github/workflows -name "*.yaml" -o -name "*.yml"); do \
71+
if grep -q "actions/setup-go" $$file; then \
72+
$(YQ) -i '(.env.GO_VERSION) = "$(GO_BUILDER_VERSION)"' $$file; \
73+
fi; \
74+
done
75+
echo "Updated go-version in workflow files to $(GO_BUILDER_VERSION)"
76+
77+
.PHONY: update-workflows-golangci-lint-version
78+
update-workflows-golangci-lint-version: yq
79+
for file in $$(find .github/workflows -name "*.yaml" -o -name "*.yml"); do \
80+
if grep -q "golangci/golangci-lint-action" $$file; then \
81+
$(YQ) -i '(.env.GOLANGCI_LINT_VERSION) = "$(GOLANGCI_LINT_VERSION)"' $$file; \
82+
fi; \
83+
done
84+
echo "Updated golangci-lint version in workflow files to $(GOLANGCI_LINT_VERSION)"
85+
86+
## Installed tools check
87+
88+
.PHONY: go-check
89+
go-check:
90+
$(call error-if-empty,$(GO),go)
91+
92+
.PHONY: git-check
93+
git-check:
94+
$(call error-if-empty,$(GIT),git)
95+
96+
## Tool installations
97+
98+
.PHONY: golangci-lint
99+
golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary.
100+
$(GOLANGCI_LINT): $(LOCALBIN)
101+
$(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/v2/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION))
102+
103+
.PHONY: yq
104+
yq: $(YQ) ## Download yq locally if necessary.
105+
$(YQ): $(LOCALBIN)
106+
$(call go-install-tool,$(YQ),github.com/mikefarah/yq/v4,$(YQ_VERSION))
107+
108+
109+
# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist
110+
# $1 - target path with name of binary
111+
# $2 - package url which can be installed
112+
# $3 - specific version of package
113+
define go-install-tool
114+
@[ -f "$(1)-$(3)" ] || { \
115+
set -e; \
116+
package=$(2)@$(3) ;\
117+
echo "Downloading $${package}" ;\
118+
rm -f $(1) || true ;\
119+
GOBIN=$(LOCALBIN) GOTOOLCHAIN=$(GO_TOOLCHAIN_AUTOINSTALL_VERSION) go install $${package} ;\
120+
mv $(1) $(1)-$(3) ;\
121+
} ;\
122+
ln -sf $(1)-$(3) $(1)
123+
endef
124+
125+
55126
define error-if-empty
56127
@if [[ -z $(1) ]]; then echo "$(2) not installed"; false; fi
57-
endef
128+
endef

README.md

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,23 @@ SDK to easy compile your hooks as a binary and integrate with addon operator
33

44
## Usage
55

6+
### Module-SDK version compatibility with Deckhouse
7+
| Module-SDK version | Deckhouse version|
8+
| --- | --- |
9+
| v0.2.X | < v1.71.0 |
10+
| v0.3.X | >=v1.71.0 |
11+
12+
### Module-SDK features compatibility with Deckhouse
13+
| Module-SDK version | Deckhouse version|
14+
| --- | --- |
15+
| Readiness Probe | >= v1.71.0 |
16+
| Applications | Coming soon |
17+
| Applications Settings check | Coming soon |
18+
| Modules v2 | Coming soon |
19+
| Modules v2 Settings check | Coming soon |
20+
| Modules Settings check | Coming soon |
21+
22+
623
### One file example
724
This file must be in 'hooks/' folder to build binary (see examples for correct layout)
825

@@ -59,7 +76,16 @@ func main() {
5976
}
6077
```
6178

62-
More examples you can find [here](./examples)
79+
More examples you can find [here](./examples).
80+
81+
### Reusable building blocks
82+
83+
| Area | What you get | Read more |
84+
| --- | --- | --- |
85+
| Common hooks | Battery-included hooks for TLS, custom certificates, storage-class changes, external auth, CRD installation. | [`common-hooks/`](./common-hooks) |
86+
| Testing — unit tests | `InputBuilder`, `StaticSnapshots`, `RecordingPatchCollector`, `JQRunOn*` and friends. | [`testing/helpers/`](./testing/helpers) |
87+
| Testing — functional tests | Deckhouse-style harness with a fake K8s cluster, snapshot generator, and patch replayer. | [`testing/framework/`](./testing/framework) |
88+
| Testing — strategy | Picking the right test layer, project-wide conventions. | [`TESTING.md`](./TESTING.md) |
6389

6490
## Adding Readiness Probes
6591

@@ -244,7 +270,52 @@ Settings validation allows you to validate module configuration values before th
244270

245271
## Testing
246272

247-
If you want to test your JQ filter, you can use JQ helper like in example [here](./pkg/jq/jq_test.go)
273+
The SDK ships with a layered testing toolkit that lets you test hooks at three levels of fidelity:
274+
275+
- **Unit tests** — quick handler-level tests using [`testing/helpers`](./testing/helpers): `InputBuilder`, real values store, `RecordingPatchCollector`, JQ helpers.
276+
- **Functional tests** — deckhouse-style end-to-end tests using [`testing/framework`](./testing/framework): a fake Kubernetes cluster, real snapshot generation, replayed patches.
277+
- **Mocks** — minimock-generated mocks for every `pkg.*` interface ([`testing/mock`](./testing/mock)) when you need precise control over a single collaborator.
278+
279+
Quick hook unit test:
280+
281+
```go
282+
import "github.com/deckhouse/module-sdk/testing/helpers"
283+
284+
func TestMyHook(t *testing.T) {
285+
in := helpers.NewInputBuilder(t).
286+
WithSnapshot("nodes", helpers.SnapshotJSON(`{"name":"n1"}`)).
287+
WithValuesJSON(`{}`).
288+
Build()
289+
290+
require.NoError(t, MyHook(context.Background(), in))
291+
require.Len(t, in.Values.GetPatches(), 1)
292+
}
293+
```
294+
295+
Quick hook functional test:
296+
297+
```go
298+
import "github.com/deckhouse/module-sdk/testing/framework"
299+
300+
func TestMyHook_Functional(t *testing.T) {
301+
f := framework.HookExecutionConfigInit(t, cfg, MyHook, `{}`, `{}`)
302+
f.KubeStateSet(`apiVersion: v1
303+
kind: Node
304+
metadata: {name: n1}`)
305+
f.RunHook()
306+
307+
require.NoError(t, f.HookError())
308+
require.Len(t, f.Snapshots().Get("nodes"), 1)
309+
}
310+
```
311+
312+
Pure JQ filter test:
313+
314+
```go
315+
helpers.JQRunOnString(ctx, ".metadata.name", `{"metadata":{"name":"x"}}`, &out)
316+
```
317+
318+
For the project-wide testing strategy and conventions, see [`TESTING.md`](./TESTING.md).
248319

249320
## For deckhouse developers
250321

0 commit comments

Comments
 (0)