Skip to content

feat: add slack manifest diff command#591

Draft
mwbrooks wants to merge 11 commits into
mainfrom
mwbrooks-manifest-diff
Draft

feat: add slack manifest diff command#591
mwbrooks wants to merge 11 commits into
mainfrom
mwbrooks-manifest-diff

Conversation

@mwbrooks

@mwbrooks mwbrooks commented Jun 13, 2026

Copy link
Copy Markdown
Member

Changelog

Added the slack manifest diff command, which prints differences between the project manifest and the app settings.

Summary

This pull request adds a read-only slack manifest diff command that compares the project manifest against the app settings on Slack and prints any differences.

  • Useful for CI/CD guardrails, pre-check before deploys, and debugging manifest conflicts.
  • Read-only - no API mutations, no file writes, no prompts.
  • Carved out from PR feat: add two-way manifest sync between project and app settings #543 to make that PR easier to review. The two-way slack manifest sync command will build on these primitives.
  • Ships without an experiment gate because it's a stand-alone read-only command. Happy to gate it, if reviewers want.
  • Exits 0 even when differences are found, to match slack manifest validate (which exits 0 even when the manifest is invalid). Standardizing exit-code semantics for scripting use-cases is a separate, project-wide conversation that should change validate and diff together.

Preview

$ slack manifest --help

SUBCOMMANDS
  diff        Show differences between the project manifest and app settings
  info        Print the app manifest of a project or app
  validate    Validate the app manifest generated by a project
$ slack manifest diff --help

Compare the project manifest with app settings and print any differences.

USAGE
  $ slack manifest diff [flags]

Testing

Outside of a project will error:

$ ./bin/slack manifest diff

# Expect:
# → This is an invalid Slack app project directory (invalid_app_directory)

Create a project:

$ ./bin/slack create my-app/
# → Select any project type

$ cd my-app/

Inside of a project with no App IDs will error:

$ ../bin/slack manifest diff

# Expect:
# →  A valid installation of this app is required to take this action (installation_required)

Create an App ID:

$ ../bin/slack manifest diff
# → Environment: "local"
# → Team: Any

Compare Project to App Settings Manifest:

$ ../bin/slack manifest diff

📚 App Manifest
   Project manifest and app settings are in sync
  • Run slack manifest diff inside a project where the local manifest matches app settings; verify the "Project manifest and app settings are in sync" message appears.
  • Edit the project manifest (e.g., change display_information.name) without deploying. Run slack manifest diff and verify the changed field is listed with both the project value and the app settings value.
  • Add a brand-new field to the project manifest. Run slack manifest diff and verify it shows up under "(only in project)".
  • Run slack manifest --help and verify diff appears alongside info and validate.
  • Run slack manifest diff --app <app-id> --token <token> (or with SLACK_AUTH_TOKEN set) and verify the command runs end-to-end with no interactive prompts — the same diff output is produced as the interactive case.

Notes

  • Display output uses the existing style package formatting carried over from the sync branch. If reviewers prefer a leaner format (e.g., one line per diff), happy to simplify in a follow-up.

Requirements

Compares the project manifest against app settings and prints any
differences. Read-only — no API mutations, no file writes, no prompts.
Useful for CI guardrails, pre-flight visibility before deploy, and
debugging manifest drift.

Carved out from the larger two-way manifest sync work (#543) so the
diff capability can land independently with a smaller diff.
@mwbrooks mwbrooks self-assigned this Jun 13, 2026
@mwbrooks mwbrooks added enhancement M-T: A feature request for new functionality semver:minor Use on pull requests to describe the release version increment labels Jun 13, 2026
@mwbrooks mwbrooks added this to the Next Release milestone Jun 13, 2026
@codecov

codecov Bot commented Jun 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.97674% with 71 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.63%. Comparing base (d7dfda7) to head (413f272).

Files with missing lines Patch % Lines
internal/manifest/display.go 10.41% 42 Missing and 1 partial ⚠️
internal/manifest/diff.go 83.50% 8 Missing and 8 partials ⚠️
cmd/manifest/diff.go 79.48% 4 Missing and 4 partials ⚠️
internal/manifest/flatten.go 86.66% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #591      +/-   ##
==========================================
- Coverage   71.67%   71.63%   -0.04%     
==========================================
  Files         226      230       +4     
  Lines       19176    19391     +215     
==========================================
+ Hits        13744    13891     +147     
- Misses       4221     4275      +54     
- Partials     1211     1225      +14     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

mwbrooks added 10 commits June 13, 2026 16:25
Shows the non-interactive form using --app and --token, matching the
intended CI guardrail use case.
Replaces "Detect manifest drift in CI" with "Show manifest differences
without prompts" so the language is plain and accessible to developers
who haven't encountered drift terminology before.
Documents flattenRecursive, diffFlat, valuesEqual, and formatValue
to match the project's existing convention (e.g. cmd/manifest/info.go
documents both exported and unexported helpers).
DisplayDiffs printed a leading blank inside the loop, which combined
with the trailing newline from style.Sectionf to produce a double
blank between the header and the first difference. Skip the blank on
the first iteration so spacing only appears between entries.
apps.manifest.export does not echo _metadata back, so projects that
declared it (e.g. SDK schema annotations) saw a noisy "(only in
project)" entry on every diff run. Apply a small ignored-paths
filter inside Diff so these never reach the user, and leave the
list extensible for any future one-sided fields.
formatValue used a byte-based slice (s[:77]) for the truncation,
which could cut a multi-byte UTF-8 character in half and produce an
invalid string in the middle of a localized field value. Switch to a
rune-based truncate helper and cover it with a test that includes
multi-byte input.
The Test_Diff and Test_Flatten loops previously only verified that
expected entries were present, so a regression that produced extra
unrelated entries would not have failed. Add a Len assertion before
the per-entry checks. Also update the function-related cases to
account for ManifestFunction.InputParameters and OutputParameters
(which lack the omitempty tag and therefore always serialize as null).
Slack's apps.manifest.export appends " (local)" to
display_information.name and features.bot_user.display_name when
returning the manifest of a dev-installed app. Fresh installs would
otherwise show two phantom diffs immediately. Suppress these
specifically when removing the suffix would make the values equal,
so genuine renames still surface.
apps.manifest.export emits settings.is_mcp_enabled: false for every
app even when the project never declared the field, so users would
otherwise see a phantom "(only in app settings)" entry on every run.
Suppress it specifically when the value is false; if a user sets it
to true locally, the resulting Modified diff still surfaces.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement M-T: A feature request for new functionality semver:minor Use on pull requests to describe the release version increment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant