Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

nais diff: show what an apply would change

オープン
#779 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
45/100
issue の種類
機能追加
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
go, kubernetes

調査の方向性

Start by examining the existing apply logic in nais/cli/internal/naisapi/apply.go to add the ChangedFields field to ResourceResult. Then, look at nais/api/internal/apply/ to understand the diff generation in diff.go and how to add a dry-run query parameter to the apply endpoint. The goal is to produce a deterministic diff output that can be rendered in the CLI, matching the behavior of the existing apply command.

索引モデルが issue の本文から書いたものです。

説明

Background

Today nais apply is a one-way door: you send manifests and find out what happened
afterwards. There is no way to see what would change before changing it — neither
interactively nor in a pull request. A nais diff command would close that gap and
make manifest changes reviewable.

The good news: most of it already exists server-side

Verified in nais/api (internal/apply/):

  • ApplyResource (client.go) does a real Kubernetes server-side apply
    (types.ApplyPatchType, FieldManager: "nais-api", Force: true), and it already
    fetches the object before patching, returning {Before, After, Created}.
  • Diff(before, after) (diff.go) already produces a structured, deterministically
    sorted
    field diff — []ResourceChangedField{Field, OldValue, NewValue} — with
    server-managed noise (status, managedFields, resourceVersion, uid,
    creationTimestamp, …) filtered out.
  • changedFields is already part of the HTTP response contract
    (model.go: ResourceResult.ChangedFields).

So the diff engine exists. It is currently only used to write activity log entries.

What is missing

nais/api:

  1. No dry-run. PatchOptions has no DryRun: []string{metav1.DryRunAll}, and the
    handler (apply.go) reads no query parameter for it.
  2. Activity log writing must be skipped when dry-running.

nais/cli:
3. internal/naisapi/apply.go ResourceResult does not even declare ChangedFields —
the server sends the diff and the client throws it away.
4. No rendering of changed fields, and no diff command.

Proposed scope

  1. Show changes in nais apply today. Add ChangedFields to the CLI's
    ResourceResult and print them after a successful apply. Requires no API change —
    the data is already on the wire. Good standalone first step.
  2. Dry-run in nais/api. Accept ?dryRun=true on
    POST /api/v1/teams/{team}/environments/{env}/apply, pass DryRunAll through to
    PatchOptions, skip the activity log, return the same changedFields.
  3. nais diff in the CLI. Same argument and flag handling as nais apply — a
    positional <path> that is a single file or a directory, --team/--environment,
    and the same mixin semantics: <base>.<env>.yaml auto-loaded per file in directory
    mode, --mixin/--set accepted only for a single file. Calls the endpoint with
    dryRun=true and renders the result.

Parity with apply matters: the whole point is that you can swap apply for diff
in a command line and have it work. That includes rendering the manifests through the
exact same mixin path, so the diff reflects what apply would actually send.

Why server-side and not client-side

A client-side diff was considered and rejected:

  • The native Valkey/OpenSearch path uses bespoke GraphQL mutations with
    replace semantics (UpdateValkeyInput requires tier and memory, the rest are
    nullable pointers), while the read query GetAllValkeys only returns
    name/memory/tier/maxMemoryPolicy/state — not databases, notifyKeyspaceEvents,
    persistenceDisabled or labels. A client-side diff would be systematically
    incomplete and would need API changes anyway.
  • A server-side dry-run reflects reality: CRD defaulting, mutating/validating webhooks
    and admission errors are all included. A client-side reconstruction is a guess.

CI/PR usage (the main motivation)

- run: nais diff .nais --team pensjon --environment prod-gcp > diff.txt
- uses: marocchino/sticky-pull-request-comment@v2
  with: { path: diff.txt }

where .nais/ holds valkey.yaml, valkey.prod-gcp.yaml, postgres.yaml, … and the
per-environment mixins are auto-loaded,

giving a reviewable comment on the PR:

Valkey valkey-pensjon-cache (prod-gcp)
  ~ spec.memory:  1GB → 4GB
  ~ spec.tier:    HighAvailability → SingleNode

Postgres pensjon-db (prod-gcp)
  + spec.extensions: [postgis]

Valkey valkey-pensjon-sessions (prod-gcp)
  + will be created

This catches things nothing else does today: that a change silently lowers
availability, that a PR creates a resource in prod nobody mentioned, and — when run
periodically on main — drift introduced outside of git.

Design notes / open questions

  • Exit code. Exit 0 even when there is a diff, with an opt-in --exit-code for
    gating (same convention as git diff --exit-code / terraform plan -detailed-exitcode). Failing the job on every change would get the check disabled.
  • Deterministic output. Diff already sorts by field path; keep it that way or
    sticky PR comments will churn on every push.
  • Auth. diff needs authentication against nais-api, unlike schema validation in
    nais apply --dry-run which needs no credentials. That difference matters for fork
    PRs and is a reason to keep both.
  • Coverage. whitelist.go in nais-api allows many kinds; diff quality is bounded
    by what SSA returns, which is fine, but dry-run does not catch asynchronous failures
    in the operators (Aiven capacity etc.). Should be communicated in output.
  • Native manifest shape. The diff is computed on the CRD object. Field paths will
    read as spec.memory etc., which maps closely to the nais manifest spec, but it is
    worth checking how it reads for the flat native envelope before settling on the
    rendering.
  • Naming of the flag/command relative to nais apply --dry-run, which does local
    schema validation without contacting the API.
主要言語
Go
スター
2
フォーク
5
平均マージ
16時間 59分
マージ済み PR(30日)
23

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

nais/cli のほかの issue

nais/cli の issue をすべて見る

似ている issue

Go の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。