Skip to content

feat(project): inject custom playbooks at arbitrary positions via playbooks order - #3191

Merged
kubesphere-prow[bot] merged 1 commit into
kubesphere:mainfrom
redscholar:feat/inject-playbooks-order
Aug 11, 2026
Merged

feat(project): inject custom playbooks at arbitrary positions via playbooks order#3191
kubesphere-prow[bot] merged 1 commit into
kubesphere:mainfrom
redscholar:feat/inject-playbooks-order

Conversation

@redscholar

Copy link
Copy Markdown
Contributor

/kind feature

What does this PR do

Generalizes playbook injection so custom playbooks can be inserted at any position of the top-level source playbook via a playbooks order list, replacing the brittle per-playbook hard-coded import slot.

Background / Motivation

Overriding/modifying KubeKey's computed default parameters used to require a hard-coded import_playbook slot (driven by an inject_playbooks_path variable) inserted into every builtin playbook. That approach was brittle, had to be repeated across all 11 builtin playbooks, and could only inject at a fixed position. Users wanted to inject at an arbitrary position relative to the original plays.

Implementation

The top-level playbook loader now merges a configured playbooks list into the original plays and sorts them by weight:

  • Original plays get weights 0, 1, 2, ... by document order.
  • Each injected entry has an explicit order (float, can be fractional or negative) and a path (template-rendered, relative to the playbook).
  • Sort comparator (deterministic; duplicate order does not error): order ascending → config items precede file plays → definition order.
  • path rendered to empty / unset variable → item skipped silently; a set path that does not exist still errors.
  • Injection applies only to the top-level (first) source playbook; imported sub-playbooks are not re-injected.
  • The hard-coded inject_playbooks_path slot was removed from builtin playbooks (it was never part of main); injection now goes exclusively through the playbooks order list. The bundled builtin/core/playbooks/hook/inject_playbooks.yaml remains as a copy-paste example, documented in docs/zh|en/reference/playbooks/inject_playbooks.md.

Key Changes

File What changed
pkg/project/project.go loadPlaybook injects configured playbooks at the top level and merges/sorts by order; adds playbookInjection + injectPlaybooks; pure import_playbook directives no longer leave an empty play in the result.
pkg/project/project_test.go New TestInjectPlaybooksOrder, TestInjectPlaybooksOrderWithImportDirective, TestInjectPlaybooksOrderEmptyPath.
pkg/project/testdata/playbooks/order_*.yaml Fixtures for the order injection tests.
docs/zh/framework/002-playbook.md, docs/en/framework/002-playbook.md Document the playbooks injection mechanism.
docs/zh/reference/playbooks/inject_playbooks.md, docs/en/reference/playbooks/inject_playbooks.md New reference page for the example injection playbook.
builtin/core/playbooks/hook/inject_playbooks.yaml Trimmed header comment, kept copy-paste examples.

Impact

  • Affected modules: pkg/project (playbook loader).
  • API changes: N/A (no exported Go API changed; playbooks is read from config generically).
  • Database / state changes: N/A.
  • Config changes: new playbooks config list (order + path) under the playbook spec; opt-in, defaults to empty (no injection).
  • Dependency changes: N/A.

Breaking Changes

None. The inject_playbooks_path hard-coded slot being removed was never present on main, so no released behavior is changed.

Which issue(s) this PR fixes:

Fixes #

Testing

Verification performed

  • Unit tests pass (go test ./pkg/project/...)
  • Integration / E2E tests pass (<command>)
  • Manual verification

Steps to verify

  1. cd builtin/core/playbooks && go test ./pkg/project/... (or from repo root: go test ./pkg/project/...).
  2. Inspect TestInjectPlaybooksOrder etc. — they assert the merged/sorted order e,d,f,g,a,b,c and empty-path skip.
  3. Manually: reference hook/inject_playbooks.yaml from a playbook's spec.playbooks with an order, e.g. order: 0.5, and confirm it is injected between the 0th and 1st original plays.

Test coverage

New unit tests cover: order-based merge/sort (TestInjectPlaybooksOrder), positioning relative to a pure import_playbook directive anchor (TestInjectPlaybooksOrderWithImportDirective), and silent skip when a path renders empty (TestInjectPlaybooksOrderEmptyPath).

Rollback

Plain revert of 27690c52 (no data/state change).

Does this PR introduce a user-facing change?

Playbook injection is now generalized: custom playbooks can be inserted at any position of the top-level source playbook via a new `playbooks` config list (`order` + `path`). The previous per-playbook `inject_playbooks_path` import slot is removed; use `playbooks` with an explicit `order` instead.

Checklist

  • Code self-reviewed, no debug code or commented-out dead code
  • No secrets, tokens, or .env files committed
  • Commit message follows Conventional Commits
  • All commits have DCO sign-off (Signed-off-by)
  • All commits are GPG-signed (GitHub shows Verified) — not signed in this dev environment (no GPG private key available); only DCO sign-off is present.
  • Tests added or updated
  • Docs / CHANGELOG updated (if needed)
  • Local lint and build pass (make build)
  • Breaking changes marked above

Additional documentation, usage docs, etc.:

Notes for Reviewer

  • GPG signing could not be performed in the current environment (no private key in the keyring); the commit carries DCO Signed-off-by only. Re-sign locally if the repo enforces the Verified badge.
  • go.work.sum was intentionally left out of this PR: it drifted only due to local go work sync / Go toolchain version differences (extra /go.mod hashes) and is unrelated to this feature.

…aybooks` order

Hard-coding an import slot in every builtin playbook was brittle and could not
place custom playbooks at arbitrary positions. Generalize injection so users can
insert custom playbooks anywhere in the top-level source playbook by weight.

- Add a `playbooks` config list; each entry has `order` (float, can be fractional
  or negative) and `path` (template-rendered). Original plays get weights
  0,1,2,... by document order; injected items are merged and sorted by a
  deterministic comparator: order ascending -> config items precede file plays
  -> definition order (duplicate order does not error).
- Empty or unset `path` is skipped silently; a set path that does not exist still
  errors. Injection applies only to the top-level (first) source playbook.
- Remove the hard-coded `inject_playbooks_path` import slot from builtin
  playbooks; injection now goes exclusively through the `playbooks` order list.
- Add unit tests for order-based injection (incl. empty-path skip and pure
  import-directive anchors) and zh/en docs (framework + reference page).

Signed-off-by: redscholar <blacktiledhouse@gmail.com>
@kubesphere-prow kubesphere-prow Bot added release-note kind/feature Categorizes issue or PR as related to a new feature. labels Aug 11, 2026
@kubesphere-prow

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: redscholar

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubesphere-prow kubesphere-prow Bot added approved Indicates a PR has been approved by an approver from all required OWNERS files. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Aug 11, 2026
@sonarqubecloud

Copy link
Copy Markdown

@redscholar redscholar added the lgtm Indicates that a PR is ready to be merged. label Aug 11, 2026
@kubesphere-prow
kubesphere-prow Bot merged commit c5e29bc into kubesphere:main Aug 11, 2026
7 checks passed
redscholar added a commit that referenced this pull request Aug 12, 2026
…aybooks` order (#3191)

Hard-coding an import slot in every builtin playbook was brittle and could not
place custom playbooks at arbitrary positions. Generalize injection so users can
insert custom playbooks anywhere in the top-level source playbook by weight.

- Add a `playbooks` config list; each entry has `order` (float, can be fractional
  or negative) and `path` (template-rendered). Original plays get weights
  0,1,2,... by document order; injected items are merged and sorted by a
  deterministic comparator: order ascending -> config items precede file plays
  -> definition order (duplicate order does not error).
- Empty or unset `path` is skipped silently; a set path that does not exist still
  errors. Injection applies only to the top-level (first) source playbook.
- Remove the hard-coded `inject_playbooks_path` import slot from builtin
  playbooks; injection now goes exclusively through the `playbooks` order list.
- Add unit tests for order-based injection (incl. empty-path skip and pure
  import-directive anchors) and zh/en docs (framework + reference page).

Signed-off-by: redscholar <blacktiledhouse@gmail.com>
redscholar added a commit to redscholar/kubekey that referenced this pull request Aug 19, 2026
…aybooks` order (kubesphere#3191)

Hard-coding an import slot in every builtin playbook was brittle and could not
place custom playbooks at arbitrary positions. Generalize injection so users can
insert custom playbooks anywhere in the top-level source playbook by weight.

- Add a `playbooks` config list; each entry has `order` (float, can be fractional
  or negative) and `path` (template-rendered). Original plays get weights
  0,1,2,... by document order; injected items are merged and sorted by a
  deterministic comparator: order ascending -> config items precede file plays
  -> definition order (duplicate order does not error).
- Empty or unset `path` is skipped silently; a set path that does not exist still
  errors. Injection applies only to the top-level (first) source playbook.
- Remove the hard-coded `inject_playbooks_path` import slot from builtin
  playbooks; injection now goes exclusively through the `playbooks` order list.
- Add unit tests for order-based injection (incl. empty-path skip and pure
  import-directive anchors) and zh/en docs (framework + reference page).

Signed-off-by: redscholar <blacktiledhouse@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. kind/feature Categorizes issue or PR as related to a new feature. lgtm Indicates that a PR is ready to be merged. release-note size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant