Skip to content

refactor: consolidate version access to slackcontext.Version(ctx)#431

Open
mwbrooks wants to merge 11 commits intomainfrom
mwbrooks-cli-version-refactor-1
Open

refactor: consolidate version access to slackcontext.Version(ctx)#431
mwbrooks wants to merge 11 commits intomainfrom
mwbrooks-cli-version-refactor-1

Conversation

@mwbrooks
Copy link
Member

@mwbrooks mwbrooks commented Mar 23, 2026

Changelog

  • N/A

Summary

This pull request consolidates version access to slackcontext.Version(ctx).

Currently, the version is accessed with version.Raw(), version.Get(), clients.config.Version, and slackcontext.Version(ctx). This is brittle, because it requires all version fields to be set to the same version. Additionally, the version value is passed as a parameter through some functions, which creates more risk of the incorrect version bring used.

  • Migrates version.Raw() callers to slackcontext.Version(ctx).
  • Standardizes on version.Raw(), previously it was a mix - most used .Raw(), but the recoveryFunc used .Get(). This could lead to difficulty associating log traces.
  • Removes clients.config.Version.
  • Replaces version string parameter with ctx parameter.
  • Simplifies mocks that required the version parameter.
  • Version now set once in main.go.

Open Questions

Test Steps

1. Version output

$ ./bin/slack --version
# → Confirm: the version string is displayed correctly (e.g. v0.x.x or a dev build SHA)

2. Version in debug output

$ ./bin/slack auth list --verbose --skip-update 2>&1 | grep -i version
# → Confirm: the CLI version appears in "Resolving logstash host"
# → Confirm: the CLI version appears in "FlushToLogstash"
# → Confirm no warnings about "version could not be found in context"

3.. User-Agent in API debug output

$ ./bin/slack auth login --verbose --skip-update 2>&1 | grep "User-Agent"
# - Confirm: the CLI version appears in "HTTP Request User-Agent"
# CTRL+C

4.. Log file version

$ ./bin/slack auth list
$ cat ~/.slack/logs/slack-debug-*.log | grep "Slack-CLI Version"
# → Confirm: last line in the log file contains the correct Slack-CLI Version value (not empty)
# → Example: "Slack-CLI Version: [v3.15.0]"

Requirements

The CLIVersion field and SetVersion functional option on ClientFactory
were a workaround for a circular dependency that no longer exists.
The API client reads version from context via slackcontext.Version(ctx),
making this indirection unnecessary. Replace with direct version.Raw()
calls.
Consumers now call version.Raw() directly instead of reading from
Config.Version, which was a redundant copy set in two places.
Remove re-added clients.Config.Version assignments that were
intentionally deleted in the Config.Version field refactor.
Replace direct version.Raw() calls with slackcontext.Version(ctx) across
all callers for improved testability via context-based dependency injection.

- slackcontext.Version(ctx) now falls back to version.Raw() when the
  context is missing the version, returning both the fallback value and
  an error so callers can log a warning
- ResolveLogstashHost no longer takes a cliVersion parameter; it reads
  the version from context internally
- Tracking tests use context-based version injection instead of mutating
  the global version.Version variable
@mwbrooks mwbrooks added this to the Next Release milestone Mar 23, 2026
@mwbrooks mwbrooks self-assigned this Mar 23, 2026
@mwbrooks mwbrooks added code health M-T: Test improvements and anything that improves code health semver:patch Use on pull requests to describe the release version increment labels Mar 23, 2026
@codecov
Copy link

codecov bot commented Mar 23, 2026

Codecov Report

❌ Patch coverage is 56.00000% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.23%. Comparing base (97fbfe8) to head (aec060b).

Files with missing lines Patch % Lines
internal/iostreams/logfile.go 0.00% 4 Missing ⚠️
main.go 0.00% 3 Missing ⚠️
internal/auth/auth.go 60.00% 1 Missing and 1 partial ⚠️
internal/tracking/tracking.go 50.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #431      +/-   ##
==========================================
- Coverage   70.27%   70.23%   -0.04%     
==========================================
  Files         220      220              
  Lines       18498    18506       +8     
==========================================
- Hits        12999    12998       -1     
- Misses       4324     4331       +7     
- Partials     1175     1177       +2     

☔ View full report in Codecov by Sentry.
📢 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.

Copy link
Member Author

@mwbrooks mwbrooks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments for the wise reviewers!


clientsMock.Auth.On("ResolveAPIHost", mock.Anything, mock.Anything, mock.Anything).
Return("api host")
clientsMock.Auth.On("ResolveLogstashHost", mock.Anything, mock.Anything, mock.Anything).
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: This is the bulk of the changes - the version parameter was removed from the ResolveLogstashHost, which simplifies our testing mocks.

Comment on lines -299 to -300
// TODO(slackcontext) Consolidate storing CLI version to slackcontext
clients.Config.Version = version.Raw()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🪓 Removing the TODO to consolidate the version to slackcontext.

Comment on lines +513 to +516
cliVersion, err := slackcontext.Version(ctx)
if err != nil {
c.io.PrintDebug(ctx, "Warning: %s", err.Error())
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: slackcontext.Version(ctx) will return an error when ctx doesn't include the version field. This could happen if the function is called with context.Background() or t.Context(), which doesn't have the Slack CLI context properties.

When an error happens, slackcontext.Version(ctx) falls back on version.Raw(), which is set by the compiler. So, it should be very reliable at returning the correct version even if the context was incorrectly passed into the function. However, still want to handle the error by printing an warning to the debug logs, so that it can be known and fixed.

TeamFlag string
TokenFlag string
NoColor bool
Version string
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🪓 shared.Config.Version

Comment on lines +174 to +176
// Version returns the CLI version associated with `ctx`. If the version is not
// found in the context, it falls back to version.Raw() and returns an error to
// signal that the context was not properly initialized.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: The important design decision is written in this comment.

setup: func(cfg *config.Config) {
cfg.Version = "v4.2.0"
ctxSetup: func(ctx context.Context) context.Context {
return slackcontext.SetVersion(ctx, "v4.2.0")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: This is a safer mock now :)

// Set context values
sessionID := uuid.New().String()
cliVersion := version.Get()
cliVersion := version.Raw()
Copy link
Member Author

@mwbrooks mwbrooks Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 discussion: This is an important decision that we should feel confident in.

Originally, the version used by slackcontext and log traces was version.Get() (always prefixes the 'v'). But, Logstash and API calls used version.Raw() (git tag, which has the 'v' by convention but not guaranteed).

This wasn't a problem because our git tags always have a prefixed 'v' (e.g. v3.15.0). However, if we created a git tag without the 'v' then version would be different in different places.

:two-cents: Consistency is more important than format. This PR does introduce the consistency, I hope, because we consolidate the version access through slackcontext.Version(ctx). w.r.t the version format, I went with version.Raw() so that we know our git tag is the source of truth. If someone creates a git tag with a different format, at least we know it all lines up. But, I'm open to either.

Thoughts?


var ctx = context.Background()
ctx = slackcontext.SetSessionID(ctx, uuid.New().String())
ctx = slackcontext.SetVersion(ctx, version.Raw())
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: Cannot re-use the cliVersion above because this is the recovery() function.

@mwbrooks mwbrooks marked this pull request as ready for review March 24, 2026 16:47
@mwbrooks mwbrooks requested a review from a team as a code owner March 24, 2026 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

code health M-T: Test improvements and anything that improves code health semver:patch 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