[GH-ISSUE #485] Pre-submission guardrails: add asc validate for metadata, assets, required fields, and age-rating completeness #136

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

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

Summary

Add a new asc validate command that performs client-side release-readiness checks before submission.

Why this matters

Teams commonly run lightweight metadata checks before upload/submit to catch preventable failures early.
Today, validation is split across commands and misses a single pre-submission gate.

Proposed command

asc validate --app "APP_ID" --version-id "VERSION_ID"
asc validate --app "APP_ID" --version-id "VERSION_ID" --platform IOS --output table
asc validate --app "APP_ID" --version-id "VERSION_ID" --strict

Checks in scope (phase 1)

  1. Metadata length limits
    • description, keywords, release notes, promotional text, name, subtitle
  2. Required field presence
    • required localizations and mandatory text fields for the target version
  3. Screenshot validity
    • screenshot dimensions/type compatibility (using the screenshot size catalog)
  4. Age-rating completeness
    • required declaration attributes present and internally consistent

Current state (verified)

  • migrate validate has offline character-limit checks, but only for imported local files.
  • Submission flow (internal/cli/submit/submit.go) does not run a holistic pre-submission validator.
  • Age-rating data and screenshot data are available through existing ASC client methods.

Output model

Return structured check results with severity:

  • error: blocks submission
  • warning: non-blocking
  • info: informational

JSON shape should include:

  • summary counts
  • per-check identifiers
  • field/resource references
  • remediation hints

Detailed implementation plan

  • Create new command package: internal/cli/validate/ with validate.go + commands.go.
  • Register in internal/cli/registry/registry.go.
  • Add validation engine package (e.g. internal/validation/) for reusable rules.
  • Move shared metadata limit constants out of migrate-only scope so both commands reuse one source of truth.
  • Add fetch layer to gather required inputs (version localizations, app info localizations, screenshot sets/assets, age rating declaration).
  • Implement rule modules:
    • metadata lengths
    • required fields
    • screenshot dimensions
    • age-rating completeness
  • Add --strict behavior to elevate warnings to errors for CI use.
  • Add cmdtests + rule unit tests covering pass/fail edge cases.
  • Document usage in README.md and submission workflow docs.

Acceptance criteria

  • asc validate exists as a top-level command and supports JSON/table/markdown output.
  • Command exits non-zero when validation errors are present.
  • Validation output contains actionable remediation hints.
  • Rules cover metadata limits, required fields, screenshot dimensions, and age-rating completeness.
  • make test passes with full coverage for validator behavior.
Originally created by @rudrankriyam on GitHub (Feb 10, 2026). Original GitHub issue: https://github.com/rudrankriyam/App-Store-Connect-CLI/issues/485 ## Summary Add a new `asc validate` command that performs client-side release-readiness checks before submission. ## Why this matters Teams commonly run lightweight metadata checks before upload/submit to catch preventable failures early. Today, validation is split across commands and misses a single pre-submission gate. ## Proposed command ```bash asc validate --app "APP_ID" --version-id "VERSION_ID" asc validate --app "APP_ID" --version-id "VERSION_ID" --platform IOS --output table asc validate --app "APP_ID" --version-id "VERSION_ID" --strict ``` ## Checks in scope (phase 1) 1. Metadata length limits - description, keywords, release notes, promotional text, name, subtitle 2. Required field presence - required localizations and mandatory text fields for the target version 3. Screenshot validity - screenshot dimensions/type compatibility (using the screenshot size catalog) 4. Age-rating completeness - required declaration attributes present and internally consistent ## Current state (verified) - `migrate validate` has offline character-limit checks, but only for imported local files. - Submission flow (`internal/cli/submit/submit.go`) does not run a holistic pre-submission validator. - Age-rating data and screenshot data are available through existing ASC client methods. ## Output model Return structured check results with severity: - `error`: blocks submission - `warning`: non-blocking - `info`: informational JSON shape should include: - summary counts - per-check identifiers - field/resource references - remediation hints ## Detailed implementation plan - [ ] Create new command package: `internal/cli/validate/` with `validate.go` + `commands.go`. - [ ] Register in `internal/cli/registry/registry.go`. - [ ] Add validation engine package (e.g. `internal/validation/`) for reusable rules. - [ ] Move shared metadata limit constants out of migrate-only scope so both commands reuse one source of truth. - [ ] Add fetch layer to gather required inputs (version localizations, app info localizations, screenshot sets/assets, age rating declaration). - [ ] Implement rule modules: - [ ] metadata lengths - [ ] required fields - [ ] screenshot dimensions - [ ] age-rating completeness - [ ] Add `--strict` behavior to elevate warnings to errors for CI use. - [ ] Add cmdtests + rule unit tests covering pass/fail edge cases. - [ ] Document usage in `README.md` and submission workflow docs. ## Acceptance criteria - [ ] `asc validate` exists as a top-level command and supports JSON/table/markdown output. - [ ] Command exits non-zero when validation errors are present. - [ ] Validation output contains actionable remediation hints. - [ ] Rules cover metadata limits, required fields, screenshot dimensions, and age-rating completeness. - [ ] `make test` passes with full coverage for validator behavior.
kerem 2026-02-26 21:33:42 +03:00
Author
Owner

@rudrankriyam commented on GitHub (Feb 11, 2026):

@cursor Please implement this issue end-to-end.

What to build

Add top-level asc validate command for pre-submission client-side checks across metadata, required fields, screenshot compatibility, and age-rating completeness.

Implementation plan

  1. Command scaffolding
  • Add internal/cli/validate/ package with validate.go + commands.go.
  • Register in internal/cli/registry/registry.go.
  • Support standard output flags (--output, --pretty) and strict mode.
  1. Validation engine
  • Add reusable rules package (e.g. internal/validation/).
  • Rule groups:
    • metadata length limits
    • required-field presence
    • screenshot dimension/type compatibility
    • age-rating completeness/consistency
  1. Data collection layer
  • Fetch required resources using existing ASC client methods (version localizations, app info localizations, screenshot sets/assets, age rating declarations).
  • Build a unified validation report with severity + remediation hints.
  1. Exit behavior
  • Non-zero exit when errors exist.
  • --strict escalates warnings to blocking behavior for CI.

New tests to write

A) Rule unit tests (internal/validation)

  • metadata over-limit/valid cases
  • required-field missing/present
  • screenshot mismatch/pass
  • age-rating incomplete/complete

B) CLI cmdtests (internal/cli/cmdtest)

  • missing required args -> usage error
  • report rendering in JSON/table
  • strict-mode exit behavior
  • mixed warning/error scenarios

C) Regression coverage

  • ensure existing migrate validate behavior remains unchanged
  • shared metadata limits stay consistent across commands

How to test locally

Run exactly:

  • make format
  • make lint
  • make test

Targeted tests:

  • go test ./internal/validation -run 'Metadata|Required|Screenshot|AgeRating'
  • go test ./internal/cli/cmdtest -run 'validate'

Done criteria

  • asc validate is available and documented.
  • Output includes actionable per-check details and summary counts.
  • Exit codes support CI gating (--strict included).
  • Coverage exists for each rule group.
  • All checks pass (format, lint, test).
<!-- gh-comment-id:3881459102 --> @rudrankriyam commented on GitHub (Feb 11, 2026): @cursor Please implement this issue end-to-end. ## What to build Add top-level `asc validate` command for pre-submission client-side checks across metadata, required fields, screenshot compatibility, and age-rating completeness. ## Implementation plan 1. **Command scaffolding** - Add `internal/cli/validate/` package with `validate.go` + `commands.go`. - Register in `internal/cli/registry/registry.go`. - Support standard output flags (`--output`, `--pretty`) and strict mode. 2. **Validation engine** - Add reusable rules package (e.g. `internal/validation/`). - Rule groups: - metadata length limits - required-field presence - screenshot dimension/type compatibility - age-rating completeness/consistency 3. **Data collection layer** - Fetch required resources using existing ASC client methods (version localizations, app info localizations, screenshot sets/assets, age rating declarations). - Build a unified validation report with severity + remediation hints. 4. **Exit behavior** - Non-zero exit when errors exist. - `--strict` escalates warnings to blocking behavior for CI. ## New tests to write ### A) Rule unit tests (`internal/validation`) - metadata over-limit/valid cases - required-field missing/present - screenshot mismatch/pass - age-rating incomplete/complete ### B) CLI cmdtests (`internal/cli/cmdtest`) - missing required args -> usage error - report rendering in JSON/table - strict-mode exit behavior - mixed warning/error scenarios ### C) Regression coverage - ensure existing migrate validate behavior remains unchanged - shared metadata limits stay consistent across commands ## How to test locally Run exactly: - `make format` - `make lint` - `make test` Targeted tests: - `go test ./internal/validation -run 'Metadata|Required|Screenshot|AgeRating'` - `go test ./internal/cli/cmdtest -run 'validate'` ## Done criteria - `asc validate` is available and documented. - Output includes actionable per-check details and summary counts. - Exit codes support CI gating (`--strict` included). - Coverage exists for each rule group. - All checks pass (`format`, `lint`, `test`).
Author
Owner

@cursor[bot] commented on GitHub (Feb 11, 2026):

  • I added a new top-level asc validate command with a reusable internal/validation engine that checks metadata length limits, required fields/locales, screenshot size compatibility, and age-rating completeness, plus --strict CI gating and table/markdown output registration. I also moved metadata limit constants into the shared validation package so migrate and validate use the same source of truth.
  • I wired the command into the registry, added report/table rendering, and updated the README with usage/examples; I also introduced a test-only ASC client constructor to support cmdtests.

Tests run:

  • go test ./internal/validation -run 'Metadata|Required|Screenshot|AgeRating'
  • go test ./internal/cli/cmdtest -run 'validate' (no tests matched due to case sensitivity)
  • go test ./internal/cli/cmdtest -run 'Validate'
  • make tools (to install gofumpt/golangci-lint), then make format
  • make lint
  • make test

View PR

Open in Cursor Open in Web

<!-- gh-comment-id:3881459405 --> @cursor[bot] commented on GitHub (Feb 11, 2026): - I added a new top-level `asc validate` command with a reusable `internal/validation` engine that checks metadata length limits, required fields/locales, screenshot size compatibility, and age-rating completeness, plus `--strict` CI gating and table/markdown output registration. I also moved metadata limit constants into the shared validation package so migrate and validate use the same source of truth. - I wired the command into the registry, added report/table rendering, and updated the README with usage/examples; I also introduced a test-only ASC client constructor to support cmdtests. Tests run: - `go test ./internal/validation -run 'Metadata|Required|Screenshot|AgeRating'` - `go test ./internal/cli/cmdtest -run 'validate'` (no tests matched due to case sensitivity) - `go test ./internal/cli/cmdtest -run 'Validate'` - `make tools` (to install gofumpt/golangci-lint), then `make format` - `make lint` - `make test` <p><a href="https://github.com/rudrankriyam/App-Store-Connect-CLI/pull/492"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/view-pr-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/view-pr-light.png"><img alt="View PR" width="86" height="28" src="https://cursor.com/assets/images/view-pr-light.png"></picture></a></p> <p><a href="https://cursor.com/background-agent?bcId=bc-fab7d7e8-15bb-46f4-8180-f622e47039aa"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;<a href="https://cursor.com/agents?id=bc-fab7d7e8-15bb-46f4-8180-f622e47039aa"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a></p>
Author
Owner

@rudrankriyam commented on GitHub (Feb 11, 2026):

Resolved by PR #492 (https://github.com/rudrankriyam/App-Store-Connect-CLI/pull/492), which is merged into main.

<!-- gh-comment-id:3887482346 --> @rudrankriyam commented on GitHub (Feb 11, 2026): Resolved by PR #492 (https://github.com/rudrankriyam/App-Store-Connect-CLI/pull/492), which is merged into main.
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#136
No description provided.