feat: support SLACK_CLI_APP_ICON_PATH env var for icon override#519
feat: support SLACK_CLI_APP_ICON_PATH env var for icon override#519srtaalej wants to merge 15 commits into
Conversation
The icon upload fallback only checked for icon.png in the project root. This adds assets/icon.png as the first fallback path, matching the convention used by slack-samples template repos and the existing auto-detection in slack_yaml.go.
Extract resolveIconPath to centralize icon fallback logic across
Install and InstallLocalApp. Search for icon.{png,jpg,jpeg,gif}
in assets/ then project root, matching all formats the API accepts.
Consolidate duplicated icon path resolution logic from install.go and slack_yaml.go into a shared internal/icon package per review feedback.
Allow users to override the app icon path via the SLACK_CLI_APP_ICON_PATH environment variable, enabling different icons per environment without changing project files. Priority chain: env var > manifest icon > icon.png in project root. Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #519 +/- ##
==========================================
+ Coverage 71.32% 71.35% +0.03%
==========================================
Files 222 222
Lines 18714 18731 +17
==========================================
+ Hits 13348 13366 +18
- Misses 4186 4187 +1
+ Partials 1180 1178 -2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| return envIconPath | ||
| } | ||
| clients.IO.PrintDebug(ctx, "SLACK_CLI_APP_ICON_PATH file not found: %s", envIconPath) | ||
| _, _ = clients.IO.WriteOut().Write([]byte(style.SectionSecondaryf("Warning: icon path from SLACK_CLI_APP_ICON_PATH not found: %s", envIconPath))) |
There was a problem hiding this comment.
SLACK_CLI_APP_ICON_PATH is set. IMHO we should print the warning and return no value instead?
| if _, err := os.Stat(envIconPath); !os.IsNotExist(err) { | ||
| return envIconPath | ||
| } |
There was a problem hiding this comment.
🪬 question: Is this a check we should also include for manifestIcon values?
| // upload icon, default to icon.png | ||
| var iconPath = slackManifest.Icon | ||
| if iconPath == "" { | ||
| if _, err := os.Stat("icon.png"); !os.IsNotExist(err) { | ||
| iconPath = "icon.png" | ||
| } | ||
| } |
There was a problem hiding this comment.
📸 thought: Keeping this inline might be alright to avoided redirected logic?
⛈️ ramble: I might suggest we instead also extract the "upload" logic that follows this since it's duplicated too, but I'd much prefer the Install and InstallLocalApp functions be merged because the logic is almost identical if this is changing-
| } | ||
|
|
||
| // Load app icon path from environment variables | ||
| var appIconPath = strings.TrimSpace(c.os.Getenv(slackAppIconPathEnv)) |
There was a problem hiding this comment.
📠 issue: This might not capture values from the .env file also. I'm wondering if this extends to other values in this file so perhaps not a blocker?
There was a problem hiding this comment.
yup all other env vars are read from system !
| APIHostFlag string | ||
| APIHostResolved string | ||
| AppFlag string | ||
| AppIconPathFlag string |
There was a problem hiding this comment.
👾 thought: Interesting to find "app icon path" reads more clear than "CLI app icon path" but this ought not block decision on:
- SLACK_APP_ICON_PATH
+ SLACK_CLI_APP_ICON_PATH🌲 ramble: I'm curious now again if "file" path needs to be specified in these values? Curious if path is clear enough on it's own...
There was a problem hiding this comment.
i can change it to CLIAppIconPath! i was matching it to the other vars here but it doesnt have to
Co-authored-by: Eden Zimbelman <eden.zimbelman@salesforce.com>
- Update constant reference to slackCLIAppIconPathEnv - Stop falling through to manifest/icon.png when env var file is missing - Add file existence check for manifest icon values - Update tests for new behavior
Co-authored-by: Eden Zimbelman <eden.zimbelman@salesforce.com>
zimeg
left a comment
There was a problem hiding this comment.
- Baseline — default icon via
slack run./bin/slack run -e set-iconConfirm output shows Updated app icon: assets/icon.png
$ slack create --branch add-app-icon -t slack-samples/bolt-js-starter-template
$ slack version
Using slack v4.0.1-ale-icon-env-var-15-g2778c01Would this be a change for this PR or can I test this with another pattern? 💡
|
📚 suggestion: Would be good to note this as |
@zimeg thanks for raising this that was an issue with the pr description. this pr doesnt check for assets/, that gets added in 509 actually. i updated the pr description! but i think i should consolidate that check into this PR to since |
Merge ale-icon-assets-fallback into ale-icon-env-var. The resolveIconPath wrapper now delegates to icon.ResolveIconPath for fallback search, gaining assets/ directory support and multiple extensions (.png, .jpg, .jpeg, .gif). Tests updated to use afero.Fs mock instead of os.Chdir.
Take main's canonical versions of icon.go, icon_test.go, and slack_yaml.go. Keep resolveIconPath wrapper in install.go that adds SLACK_CLI_APP_ICON_PATH env var priority on top of icon.ResolveIconPath.
a044dbe to
805fdaf
Compare
| _, _ = clients.IO.WriteOut().Write([]byte(style.SectionSecondaryf("Warning: icon path from manifest not found: %s", manifestIcon))) | ||
| return "" | ||
| } | ||
| return icon.ResolveIconPath(clients.Fs, "") |
There was a problem hiding this comment.
| return icon.ResolveIconPath(clients.Fs, "") | |
| return icon.ResolveIconPath(clients.Fs) |
🪓 suggestion: Let's remove arguments that aren't used as part of these changes!
There was a problem hiding this comment.
🪬 ramble: It's confusing to have multiple functions to resolve icon path functions IMHO and might consider the one of this file as a source of truth because we're writing output here. I'd be curious in refactoring the rest of the icon package inline if that's reasonable but no blocker for this PR!
Changelog
Add
SLACK_CLI_APP_ICON_PATHenvironment variable to override the icon file path used during app install and local run. When set, the specified path takes priority over the manifesticonfield and the default icon file search. A warning is displayed if the configured path does not exist.Summary
SLACK_CLI_APP_ICON_PATHenvironment variable support to override the app icon path at install/deploy timeSLACK_CLI_APP_ICON_PATHenv var > manifesticonfield >assets/and root fallback (viaicon.ResolveIconPath)resolveIconPathwrapper ininstall.gothat adds env var priority + path validation with warnings on top oficon.ResolveIconPathTest plan
Unit tests
go test ./internal/config/ -run Test_DotEnv— env var loading (set, empty, whitespace trimming)go test ./internal/pkg/apps/ -run Test_resolveIconPath— priority chain scenarios (env var, manifest, assets fallback, root fallback, missing paths)Manual testing
From a Slack app project directory:
Override via env var
export SLACK_CLI_APP_ICON_PATH=icon.png ./bin/slack run -e set-iconConfirm output shows
Updated app icon: icon.pngInvalid env var path shows warning
export SLACK_CLI_APP_ICON_PATH=/nonexistent/icon.png ./bin/slack run -e set-iconConfirm warning:
icon path from SLACK_CLI_APP_ICON_PATH not foundManifest icon field used when env var unset
unset SLACK_CLI_APP_ICON_PATH ./bin/slack run -e set-iconIf manifest returns
"icon": "path/to/icon.png", confirm that path is usedFallback to
assets/icon.pngoricon.pngin project rootWith no env var and no manifest icon field, confirm icon auto-detection finds
assets/icon.png(oricon.pngin root)