xpkg build: GoTemplate function input kind field buried after large block scalar due to JSON key reordering
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 55/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
- 技術スタック
- go
- 領域
- build-system, cli
調査の方向性
crossplane-runtime/pkg/xpkg/build.go の encode() から始め、埋め込まれた RawExtension.Raw の JSON が YAMLToJSON() を介してどのようにシリアライズされるかを追ってください。xpkg build で問題を再現し、package.yaml を調べてください。次に、apiVersion と kind が大きな inline.template ブロックの前に並んで現れること、およびビルドされたパッケージが正常にインストールされることを確認してください。
索引モデルが issue の本文から書いたものです。
説明
Describe the bug
`crossplane xpkg build` reorders fields in embedded `RawExtension` objects alphabetically (via `sigs.k8s.io/yaml.YAMLToJSON()`) during YAML serialization. For a `function-go-templating` pipeline step input, this buries `kind: GoTemplate` after the entire `inline.template` block scalar — which can be hundreds or thousands of lines long.
Some YAML parsers and the Crossplane package reader fail to correctly handle a `kind` field that appears after a very large literal block scalar, causing installed ConfigurationRevisions to fail with:
spec.pipeline[N].input.kind: Required value
This became visible with Crossplane v2.2.0, which added strict validation requiring `kind` in all pipeline step inputs. See crossplane/crossplane#7819.
Root cause
The `encode()` function in `crossplane-runtime/pkg/xpkg/build.go` re-serializes all package objects through the Kubernetes JSON serializer:
- Source YAML is parsed → stored as `*v1.Composition` with `Input.Raw` = JSON bytes
- `sigs.k8s.io/yaml.YAMLToJSON()` converts the YAML map to JSON with alphabetically sorted keys
- Original YAML field order: `apiVersion → kind → source → inline`
- JSON (and final YAML) field order: `apiVersion → inline → kind → source`
Result in `package.yaml`:
```yaml
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
inline:
template: |
{{- ... hundreds of lines of go template ... }}
kind: GoTemplate # ← buried after the block scalar
source: Inline
```
Steps to reproduce
- Create a Composition with a `function-go-templating` step whose `inline.template` is >100 lines
- Run `crossplane xpkg build`
- Extract `package.yaml` from the built `.xpkg`:
tar xf package.xpkg tar xzf <layer>.tar.gz - Search for `kind: GoTemplate` — it is present but appears after the entire template block, not next to `apiVersion:`
- Install the package on a Crossplane v2.2.0+ cluster → ConfigurationRevision fails
Expected behaviour
`kind: GoTemplate` appears adjacent to `apiVersion: gotemplating.fn.crossplane.io/v1beta1` in the serialized `package.yaml`, matching the source file and ensuring reliable parsing.
Suggested fix
In `crossplane-runtime/pkg/xpkg/build.go`, modify `encode()` to re-order keys in `RawExtension.Raw` JSON so that TypeMeta fields (`apiVersion`, `kind`) appear first before emitting. Concretely: after marshaling each object to JSON, walk any embedded `RawExtension` fields and produce a new JSON object with `apiVersion`/`kind` promoted to the front.
An alternative is to add a normalization pass in the `xpkg build` command (`cmd/crossplane/xpkg/build.go`) after `c.builder.Build()` — extract `package.yaml` from the built image, re-insert `kind`/`apiVersion` immediately after each other in embedded resource blocks, and rebuild the layer.
Workaround
Post-process the built `.xpkg` to insert `kind: GoTemplate` immediately after each `apiVersion: gotemplating.fn.crossplane.io/v1beta1` line. This is what the affected package repo currently does as a stop-gap.
Related
- crossplane/crossplane#7819 — Crossplane v2.2.0 added the `kind` validation requirement that surfaces this bug
- 主要言語
- Go
- スター
- 19
- フォーク
- 31
- 平均マージ
- 2日 12時間
- マージ済み PR(30日)
- 52
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
crossplane/cli のほかの issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
crossplane/cli#282 ·
-
enhancement
難易度 3/5 1〜2日 初心者へのやさしさ 68/100
crossplane/cli#386 · リアクション 1 件 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 52/100
crossplane/cli#384 ·
-
crossplane/cli#379 · 担当者 1 名 ·
-
bug
難易度 4/5 3〜5日 初心者へのやさしさ 68/100
crossplane/cli#370 · リアクション 1 件 ·
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
bazel-contrib/rules_go#4726 · コメント 1 件 ·
-
area/auto-scaling area/monitoring area/ops-productivity kind/enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
-
Type/Improvement
難易度 1/5 1〜3時間 初心者へのやさしさ 90/100
OpenNSW/nsw-srilanka#522 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 92/100