[GH-ISSUE #586] feat: Add metadata diff command (asc diff) #161

Closed
opened 2026-02-26 21:33:50 +03:00 by kerem · 0 comments
Owner

Originally created by @rudrankriyam on GitHub (Feb 17, 2026).
Original GitHub issue: https://github.com/rudrankriyam/App-Store-Connect-CLI/issues/586

Summary

Add a first-class diff command to compare App Store Connect state vs another state (remote vs remote, or local files vs remote) and emit a deterministic “plan”/diff artifact.

Proposed entrypoint:

asc diff <scope> [flags]

Why this matters

asc is already strong at listing and updating resources, but teams still struggle with:

  • “What will change if I run this upload?”
  • “Did our metadata drift from what’s in git?”
  • “What changed between version A and version B?”

A diff command makes metadata workflows auditable and CI-friendly.

Current state (verified)

  • No asc diff command exists.
  • Partial building blocks exist:
    • asc localizations download/upload
    • asc screenshots ... (plans + uploads)
    • asc migrate import/export (fastlane interop)

Proposed UX (phase 1: localizations)

Start narrow and useful:

# Compare local file/directory to remote localizations
asc diff localizations \
  --app "APP_ID" \
  --version "1.2.3" \
  --path "./metadata" \
  --output json

# Compare two remote versions
asc diff localizations --app "APP_ID" --from-version "1.2.3" --to-version "1.2.4"

Flags (proposal):

  • --app (required)
  • Source selection:
    • --path (local source) OR --from-version (remote source)
  • Target selection:
    • --version (remote target) OR --to-version (remote target)
  • --output json|table|markdown (default json)
  • --pretty (when json)

Output model

Default JSON output is a deterministic plan:

  • adds[], updates[], deletes[]
  • each item includes a stable identity key and a concise reason

Example:

{
  "scope": "localizations",
  "appId": "123",
  "targetVersion": "1.2.3",
  "adds": [{"locale":"fr-FR","field":"description"}],
  "updates": [{"locale":"en-US","field":"keywords","from":"a","to":"b"}],
  "deletes": []
}

Follow-ups (future scopes)

  • asc diff screenshots (plan file vs remote)
  • asc diff app-info / asc diff version-metadata
  • asc diff pricing

Implementation notes

  • Prefer implementing diff against the same normalized in-memory representation used by upload/update commands.
  • Use strict validation: unknown fields in local files should be an exit usage (2), not silently ignored.

Test plan (TDD-first)

  • cmdtests:
    • missing required flags returns exit usage (2)
    • JSON output parses + is deterministic
    • remote-vs-remote diff uses httptest fixtures
  • unit tests:
    • normalization rules (whitespace, ordering)
    • diff algorithm correctness

Acceptance criteria

  • asc diff localizations exists and is self-documenting.
  • Outputs a deterministic plan artifact suitable for CI.
  • No mutations; safe to run anytime.
  • make test passes.
Originally created by @rudrankriyam on GitHub (Feb 17, 2026). Original GitHub issue: https://github.com/rudrankriyam/App-Store-Connect-CLI/issues/586 ## Summary Add a first-class diff command to compare App Store Connect state vs another state (remote vs remote, or local files vs remote) and emit a deterministic “plan”/diff artifact. Proposed entrypoint: ```bash asc diff <scope> [flags] ``` ## Why this matters `asc` is already strong at *listing* and *updating* resources, but teams still struggle with: - “What will change if I run this upload?” - “Did our metadata drift from what’s in git?” - “What changed between version A and version B?” A diff command makes metadata workflows auditable and CI-friendly. ## Current state (verified) - No `asc diff` command exists. - Partial building blocks exist: - `asc localizations download/upload` - `asc screenshots ...` (plans + uploads) - `asc migrate import/export` (fastlane interop) ## Proposed UX (phase 1: localizations) Start narrow and useful: ```bash # Compare local file/directory to remote localizations asc diff localizations \ --app "APP_ID" \ --version "1.2.3" \ --path "./metadata" \ --output json # Compare two remote versions asc diff localizations --app "APP_ID" --from-version "1.2.3" --to-version "1.2.4" ``` Flags (proposal): - `--app` (required) - Source selection: - `--path` (local source) OR `--from-version` (remote source) - Target selection: - `--version` (remote target) OR `--to-version` (remote target) - `--output json|table|markdown` (default json) - `--pretty` (when json) ## Output model Default JSON output is a deterministic plan: - `adds[]`, `updates[]`, `deletes[]` - each item includes a stable identity key and a concise reason Example: ```json { "scope": "localizations", "appId": "123", "targetVersion": "1.2.3", "adds": [{"locale":"fr-FR","field":"description"}], "updates": [{"locale":"en-US","field":"keywords","from":"a","to":"b"}], "deletes": [] } ``` ## Follow-ups (future scopes) - `asc diff screenshots` (plan file vs remote) - `asc diff app-info` / `asc diff version-metadata` - `asc diff pricing` ## Implementation notes - Prefer implementing diff against the same normalized in-memory representation used by upload/update commands. - Use strict validation: unknown fields in local files should be an exit usage (2), not silently ignored. ## Test plan (TDD-first) - [ ] cmdtests: - [ ] missing required flags returns exit usage (2) - [ ] JSON output parses + is deterministic - [ ] remote-vs-remote diff uses httptest fixtures - [ ] unit tests: - [ ] normalization rules (whitespace, ordering) - [ ] diff algorithm correctness ## Acceptance criteria - [ ] `asc diff localizations` exists and is self-documenting. - [ ] Outputs a deterministic plan artifact suitable for CI. - [ ] No mutations; safe to run anytime. - [ ] `make test` passes.
kerem 2026-02-26 21:33:50 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/App-Store-Connect-CLI#161
No description provided.