Skip to content

Add profile-based auth configuration#366

Open
art049 wants to merge 2 commits into
mainfrom
profiles-auth-environments
Open

Add profile-based auth configuration#366
art049 wants to merge 2 commits into
mainfrom
profiles-auth-environments

Conversation

@art049
Copy link
Copy Markdown
Member

@art049 art049 commented May 23, 2026

Summary

  • add named CodSpeed profiles with per-profile auth, API URL, and upload URL
  • resolve the selected profile once inside CodSpeedConfig so downstream commands keep using effective config.auth/api_url/upload_url
  • add global --profile / CODSPEED_PROFILE and profile list/show/set/use commands
  • migrate legacy single-token config into profiles.default while preserving existing overrides

Testing

  • cargo fmt --check
  • cargo check (blocked: missing crates/instrument-hooks-bindings/instrument-hooks/dist/core.c)
  • cargo test config::tests (blocked: missing crates/instrument-hooks-bindings/instrument-hooks/dist/core.c)

Note: the commit was created with --no-verify because the clippy pre-commit hook hits the same missing instrument-hooks submodule artifact.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 23, 2026

Merging this PR will not alter performance

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

✅ 7 untouched benchmarks


Comparing profiles-auth-environments (3e259b8) with main (f4d8493)

Open in CodSpeed

@art049 art049 force-pushed the profiles-auth-environments branch from 9a910f9 to e1e94b4 Compare May 23, 2026 04:23
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 24, 2026

Greptile Summary

This PR introduces named CodSpeed profiles with per-profile auth, API URL, and upload URL, adds global --profile / CODSPEED_PROFILE flags, and new profile list/show/set/use subcommands. It also extracts the existing shell-session KV mechanism into a generic shell_session module reused by both use-mode and profile selection, and migrates legacy single-token config into profiles.default.

  • Profile resolution: CodSpeedConfig::load_with_profile resolves the selected profile once at startup, populating flat auth/api_url/upload_url fields that all downstream commands consume.
  • Shell-session state: both runner-mode and active-profile selection now share the same PID-keyed file store under $XDG_RUNTIME_DIR.
  • Config persistence: persist() calls sync_effective_profile() to write effective values back into the stored profile before serialising; however this reads the flat fields resolved at load time rather than any values written directly via profile_mut(), which means profile set on the currently-active profile silently discards changes (flagged in prior review threads).

Confidence Score: 4/5

Safe to merge with one functional fix: the profile list command never shows the active-profile marker when using the implicit default, which is the most common state for new users of this feature.

The shell-session extraction and config-loading refactor are clean and well-tested. The one concrete wrong-output bug is in profile list: it reads load_shell_session_profile() directly and compares it to each name, so the * marker is always absent unless the user has explicitly called profile use — the default profile (the overwhelmingly common case) is never highlighted.

src/cli/profile.rs — the list() function uses the wrong source for the active-profile name.

Important Files Changed

Filename Overview
src/config.rs Core profile-based config logic: adds ProfileConfig/BTreeMap, migration from legacy auth, resolve_selected_profile, and sync_effective_profile. The sync_effective_profile reads back the already-resolved flat fields (which don't reflect direct profile_mut edits), so profile set for the selected profile silently discards changes — issues flagged in prior review threads.
src/cli/profile.rs New profile subcommand (list/show/set/use). The list() function misidentifies the active profile: it calls load_shell_session_profile() independently instead of using config.selected_profile_name(), so the * marker is never shown when using the implicit default profile.
src/cli/mod.rs Refactors CLI entry point: config is now loaded once via load_config() and passed downstream; api_url flag changed from String to Option; upload_url from profile is injected into Run/Exec args.
src/shell_session.rs New generic shell-session KV store extracted from runner_mode/shell_session.rs; logic is unchanged, now parameterized by kind string for reuse by both use-mode and profile selection.
src/cli/auth.rs login() now accepts a pre-loaded CodSpeedConfig instead of loading its own, and displays the active profile name in the success message.
scripts/init-worktree.sh New post-checkout hook that auto-initialises submodules and pre-commit hooks when a git worktree is created (detected via the all-zero PRE_COMMIT_FROM_REF).
CONTRIBUTING.md Adds Initial Setup section; contains a typo: prek install should be pre-commit install.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    CLI["CLI::parse()"] --> LC["load_config()\nCodSpeedConfig::load_with_profile"]
    LC --> DISK["Read ~/.config/codspeed/config.yaml"]
    DISK --> MIG["migrate_legacy_auth()\nmove top-level auth → profiles.default"]
    MIG --> EDP["ensure_default_profile()"]
    EDP --> RSP["resolve_selected_profile()"]
    RSP --> SESSION["load_shell_session_profile()\n(XDG_RUNTIME_DIR/codspeed_profile/ppid)"]
    SESSION -->|"name found"| PROF["Look up ProfileConfig\nfrom BTreeMap"]
    SESSION -->|"None → use 'default'"| PROF
    PROF --> FLAT["Populate flat fields:\nconfig.auth / api_url / upload_url"]
    FLAT --> COMMANDS["Dispatch command"]
    COMMANDS --> AUTH["auth login/status"]
    COMMANDS --> RUN["run / exec"]
    COMMANDS --> PLIST["profile list"]
    COMMANDS --> PSET["profile set → profile_mut(name)"]
    PSET --> PERSIST["persist() → sync_effective_profile()"]
    AUTH --> PERSIST
    COMMANDS --> PUSE["profile use → register_shell_session_profile()"]
Loading

Reviews (3): Last reviewed commit: "feat(cli): add profile system with shell..." | Re-trigger Greptile

Comment thread src/config.rs
Comment thread src/config.rs
@art049 art049 force-pushed the profiles-auth-environments branch from e1e94b4 to 9d098b3 Compare May 24, 2026 15:00
art049 and others added 2 commits May 24, 2026 17:25
Add a pre-commit `post-checkout` stage hook that detects `git worktree
add` (signalled by an all-zero previous HEAD) and initializes
submodules + reinstalls pre-commit hooks in the new worktree. The
config opts both stages into `default_install_hook_types` so a plain
`prek install` wires up everything.

Co-Authored-By: Claude <noreply@anthropic.com>
Introduce named profiles (each with its own auth token and optional
api-url/upload-url) under `profiles` in the config. The legacy
top-level `auth.token` is migrated into `profiles.default` on load.

Profile selection follows the same precedence model as runner mode:
`--profile` / `CODSPEED_PROFILE` env var, then a per-shell-session
selection registered by `codspeed profile use <name>` (parent-PID
keyed file under `$XDG_RUNTIME_DIR/codspeed_profile`), then the
built-in `default` profile. There is no globally persisted default
profile.

The parent-PID shell-session machinery used by `codspeed use <mode>`
is extracted into a generic `shell_session` module so both features
share the same implementation.

Co-Authored-By: Claude <noreply@anthropic.com>
@art049 art049 force-pushed the profiles-auth-environments branch from 9d098b3 to 3e259b8 Compare May 24, 2026 16:24
Comment thread src/cli/profile.rs
Comment on lines +56 to +71
fn list(config_name: Option<&str>) -> Result<()> {
let config = CodSpeedConfig::load_with_override(config_name, None)?;
let active = load_shell_session_profile()?;

info!("{}", style("Profiles").bold());
for name in config.profiles.keys() {
let marker = if Some(name) == active.as_ref() {
"*"
} else {
" "
};
info!(" {marker} {name}");
}

Ok(())
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 The active-profile marker in profile list is never shown for the implicit default profile. load_shell_session_profile() returns None unless the user has explicitly called codspeed profile use, so the * marker is absent for every profile in the common case. The config already resolves the effective profile name into config.selected_profile_name() — use that directly instead of calling load_shell_session_profile() a second time.

Suggested change
fn list(config_name: Option<&str>) -> Result<()> {
let config = CodSpeedConfig::load_with_override(config_name, None)?;
let active = load_shell_session_profile()?;
info!("{}", style("Profiles").bold());
for name in config.profiles.keys() {
let marker = if Some(name) == active.as_ref() {
"*"
} else {
" "
};
info!(" {marker} {name}");
}
Ok(())
}
fn list(config_name: Option<&str>) -> Result<()> {
let config = CodSpeedConfig::load_with_override(config_name, None)?;
let active = config.selected_profile_name().to_owned();
info!("{}", style("Profiles").bold());
for name in config.profiles.keys() {
let marker = if name == &active { "*" } else { " " };
info!(" {marker} {name}");
}
Ok(())
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant