Skip to content

decrating: absorb shipper-auth into shipper::ops::auth (full absorption)#63

Merged
EffortlessSteven merged 2 commits into
mainfrom
feature/decrating-absorb-auth-full
Apr 15, 2026
Merged

decrating: absorb shipper-auth into shipper::ops::auth (full absorption)#63
EffortlessSteven merged 2 commits into
mainfrom
feature/decrating-absorb-auth-full

Conversation

@EffortlessSteven

Copy link
Copy Markdown
Member

Summary

Stacks on #51 (the dual-implementation cleanup). Reviewer should merge #51 first.

Full absorption of the shipper-auth microcrate into the shipper library:

  • Move the 1762-LOC shipper-auth/src/lib.rs + the 333-LOC post-decrating: Phase 1 (hard) — collapse auth dual implementation, preserve shim fallback #51 shim (crates/shipper/src/auth.rs) into crates/shipper/src/ops/auth/.
  • Split into 4 focused sub-files:
    • mod.rs (facade + top-level resolve_token/detect_auth_type with whitespace-trim and legacy-credentials fallback)
    • resolver.rs (env-var + credentials-file resolution; AuthInfo/TokenSource; mask_token, cargo_home_path, has_token)
    • credentials.rs (credentials.toml parsing — both strict micro-form and extended alias-aware form; list_configured_registries)
    • oidc.rs (trusted-publishing env-var detection)
  • Introduce new pub(crate) mod ops; scaffold in lib.rs (per decrating plan Phase 2).
  • Preserve shipper::auth::* public API via a thin facade module in lib.rs that re-exports from crate::ops::auth.
  • Delete standalone crates/shipper-auth/, the in-tree auth.rs, the shipper-auth dep from shipper, and the workspace-members entry.
  • Clean up shipper-auth references from CI, docs, and release checklist.

Split rationale

The module-level CLAUDE.md records the responsibility split:

  • resolver.rs owns the env-var resolution path and the diagnostic types that surface through shipper doctor.
  • credentials.rs owns all TOML parsing, including the two forms (strict microcrate form, and the extended form that handles crates-io/crates.io/crates_io/nested [registries.crates.io]).
  • oidc.rs is a self-contained 4-line check that benefits from being its own test surface.
  • mod.rs is a thin public-to-crate facade that layers whitespace-trim + legacy-credentials-filename fallback on top.

Validation

Check Result
cargo check --workspace --all-targets clean
cargo fmt --all -- --check clean
cargo clippy -p shipper --all-targets --all-features -- -D warnings clean
cargo test -p shipper ops::auth 123 passed, 0 failed
cargo test -p shipper 824 + 5 integration suites all green
cargo test -p shipper-cli full suite green (380+ tests)
cargo build -p shipper-cli green

Public API surface

External consumers (fuzz targets, facade_integration.rs, and the CLI at shipper::auth::detect_auth_type) continue to compile unchanged thanks to the pub mod auth { pub use crate::ops::auth::...; } facade in lib.rs.

Snapshots

All 34 kept snapshots transferred from crates/shipper-auth/src/snapshots/ to crates/shipper/src/ops/auth/snapshots/ with renamed filenames (new crate + module path prefix) and edited source: headers. 3 orphaned hardening_snapshots files were dropped — no test code in the original microcrate referenced them.

Test plan

@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@coderabbitai

coderabbitai Bot commented Apr 15, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@EffortlessSteven has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 6 minutes and 5 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 6 minutes and 5 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 401f0d6c-a3d8-4373-ada5-6bb380d39426

📥 Commits

Reviewing files that changed from the base of the PR and between 2c31477 and f1b06f1.

⛔ Files ignored due to path filters (43)
  • Cargo.lock is excluded by !**/*.lock
  • crates/shipper-auth/src/snapshots/shipper_auth__tests__edge_snapshots__snapshot_token_source_none.snap is excluded by !**/*.snap
  • crates/shipper-auth/src/snapshots/shipper_auth__tests__hardening_snapshots__snapshot_credentials_integer_token_error.snap is excluded by !**/*.snap
  • crates/shipper-auth/src/snapshots/shipper_auth__tests__hardening_snapshots__snapshot_custom_registry_env_precedence_over_file.snap is excluded by !**/*.snap
  • crates/shipper-auth/src/snapshots/shipper_auth__tests__hardening_snapshots__snapshot_env_var_name_mapping.snap is excluded by !**/*.snap
  • crates/shipper-auth/src/snapshots/shipper_auth__tests__snapshots__snapshot_credentials_crates_io_registry_section.snap is excluded by !**/*.snap
  • crates/shipper-auth/src/snapshots/shipper_auth__tests__snapshots__snapshot_credentials_custom_registry_section.snap is excluded by !**/*.snap
  • crates/shipper-auth/src/snapshots/shipper_auth__tests__snapshots__snapshot_credentials_legacy_toplevel_format.snap is excluded by !**/*.snap
  • crates/shipper-auth/src/snapshots/shipper_auth__tests__snapshots__snapshot_list_configured_registries_empty.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__credentials__tests__error_message_snapshots__error_msg_credentials_not_found.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__credentials__tests__error_message_snapshots__error_msg_empty_credentials.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__credentials__tests__error_message_snapshots__error_msg_malformed_toml.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__credentials__tests__error_message_snapshots__error_msg_token_wrong_registry.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__credentials__tests__snapshots__snapshot_credentials_crates_io_registry_section.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__credentials__tests__snapshots__snapshot_credentials_custom_registry_section.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__credentials__tests__snapshots__snapshot_credentials_file_with_all_formats.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__credentials__tests__snapshots__snapshot_credentials_legacy_toplevel_format.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__credentials__tests__snapshots__snapshot_error_malformed_credentials_file.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__credentials__tests__snapshots__snapshot_error_missing_credentials_file.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__credentials__tests__snapshots__snapshot_error_token_not_found_for_registry.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__credentials__tests__snapshots__snapshot_list_configured_registries_empty.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__credentials__tests__snapshots__snapshot_list_configured_registries_mixed.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__credentials__tests__snapshots__snapshot_list_registries_many.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__edge_snapshots__snapshot_auth_info_not_detected.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__edge_snapshots__snapshot_auth_info_with_credentials_file.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__edge_snapshots__snapshot_auth_info_with_env_default.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__edge_snapshots__snapshot_auth_info_with_env_registry.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__edge_snapshots__snapshot_mask_token_long_value.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__edge_snapshots__snapshot_mask_token_short_values.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__edge_snapshots__snapshot_resolve_unicode_token.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__edge_snapshots__snapshot_resolve_whitespace_token.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__edge_snapshots__snapshot_token_source_credentials_file.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__edge_snapshots__snapshot_token_source_env_default.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__edge_snapshots__snapshot_token_source_env_registry.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__edge_snapshots__snapshot_token_source_none.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__error_message_snapshots__error_msg_missing_token.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__error_message_snapshots__error_msg_token_source_none.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__snapshots__snapshot_auth_info_default.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__snapshots__snapshot_resolve_token_custom_registry_from_credentials.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__snapshots__snapshot_resolve_token_from_credentials_file.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__snapshots__snapshot_resolve_token_from_env_default.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__snapshots__snapshot_resolve_token_from_env_registry.snap is excluded by !**/*.snap
  • crates/shipper/src/ops/auth/snapshots/shipper__ops__auth__resolver__tests__snapshots__snapshot_resolve_token_none_found.snap is excluded by !**/*.snap
📒 Files selected for processing (22)
  • .github/workflows/ci.yml
  • .github/workflows/mutation.yml
  • Cargo.toml
  • RELEASE_CHECKLIST_v0.3.0.md
  • crates/shipper-auth/CLAUDE.md
  • crates/shipper-auth/Cargo.toml
  • crates/shipper-auth/README.md
  • crates/shipper-auth/proptest-regressions/lib.txt
  • crates/shipper-cli/Cargo.toml
  • crates/shipper/Cargo.toml
  • crates/shipper/src/auth.rs
  • crates/shipper/src/engine.rs
  • crates/shipper/src/lib.rs
  • crates/shipper/src/ops/auth/CLAUDE.md
  • crates/shipper/src/ops/auth/credentials.rs
  • crates/shipper/src/ops/auth/mod.rs
  • crates/shipper/src/ops/auth/oidc.rs
  • crates/shipper/src/ops/auth/resolver.rs
  • crates/shipper/src/ops/mod.rs
  • docs/architecture.md
  • docs/testing.md
  • templates/circleci-config.yml
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/decrating-absorb-auth-full

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d9321ef820

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 101 to 103
let env_var = format!(
"{}{}_TOKEN",
CARGO_REGISTRIES_TOKEN_PREFIX,

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 Badge Normalize all non-alnum chars in registry env var names

This resolver only rewrites - to _ when building CARGO_REGISTRIES_<NAME>_TOKEN, so registry names containing other punctuation (for example my.registry) are looked up with the wrong env var (CARGO_REGISTRIES_MY.REGISTRY_TOKEN) and the token is missed. In this commit, shipper::auth::resolve_token is now wired through this absorbed resolver path for the main crate, so users who previously relied on Cargo-style normalization (non-alphanumeric -> _) can regress to false "no token" preflight/publish failures even when the correct env var is set.

Useful? React with 👍 / 👎.

Delete the stale 1212-LOC in-tree `crates/shipper/src/auth.rs` and promote
the 333-LOC shim from `auth_micro.rs` to canonical `auth.rs`. The shim was
already the production code path (CLI defaults to `micro-all`), and it is
more than a thin re-export: it layers credential-file fallback and OIDC
detection on top of the `shipper-auth` microcrate.

Preserved shim behavior:
- Delegation to `shipper_auth::resolve_token` as first-choice path.
- Legacy fallback to `\$CARGO_HOME/credentials.toml` and the older
  `credentials` file when the microcrate returns no token.
- crates.io alias handling (`crates.io`, `crates_io`, and the
  nested-table `[registries.crates.io]` TOML shape).
- `detect_auth_type` / `detect_auth_type_from_token` helpers for
  OIDC trusted-publishing diagnostics.
- All `serial_test` unit tests covering resolution order, env
  precedence, legacy credentials file, and OIDC detection.

Public API surface is a superset of the deleted in-tree module
(`resolve_token`, `detect_auth_type`, `detect_auth_type_from_token`),
so no call-site changes were required.

Feature-flag cleanup:
- Remove `micro-auth` feature from `crates/shipper/Cargo.toml`; make
  `shipper-auth` a non-optional dependency.
- Drop `micro-auth` from the `micro-all` feature list.
- Remove `micro-auth` from `crates/shipper-cli/Cargo.toml` features.
- Remove `micro-auth` from the BDD feature-set matrix in
  `.github/workflows/ci.yml` and `templates/circleci-config.yml`.
- Update `docs/architecture.md` and `docs/testing.md` to reflect that
  `shipper-auth` is now a required dependency.

Validation:
- `cargo test -p shipper` — all tests pass (incl. 8 auth + 4 facade
  integration auth tests).
- `cargo test -p shipper-cli` — all tests pass.
- `cargo build -p shipper-cli` — succeeds.
- `cargo check --workspace` — succeeds.
- `cargo clippy -p shipper --all-targets --all-features -- -D warnings`
  — clean.

Net LOC removed: ~879 (1212 deleted in-tree file minus 333 promoted shim).
Stacks on PR #51 (which did the dual-implementation cleanup). Move the
1762-LOC standalone shipper-auth crate into crates/shipper/src/ops/auth/
as crate-private modules, split into mod.rs (facade), resolver.rs
(env + credentials-file token resolution, AuthInfo/TokenSource,
mask_token, cargo_home_path), credentials.rs (credentials.toml parsing,
legacy format + crates.io aliases, list_configured_registries), and
oidc.rs (trusted-publishing env-var detection). Preserves the 333-LOC
credential fallback path that PR #51 promoted to canonical (now the
extended lookup in credentials::token_from_credentials_file_extended).

Delete the standalone crate, the dedupped in-tree auth.rs, and the
shipper-auth dep from shipper. Remove from workspace members. Drop
shipper-auth references from .github/workflows/mutation.yml,
docs/architecture.md, docs/testing.md, and RELEASE_CHECKLIST_v0.3.0.md.

shipper::auth::* public re-export preserved via a thin facade module in
lib.rs that re-exports from the new crate-private crate::ops::auth --
no breaking change for external consumers (fuzz targets and
facade_integration tests continue to compile unchanged).

All snapshot tests moved to crates/shipper/src/ops/auth/snapshots/ with
renamed source paths. 3 orphaned hardening_snapshots files (no tests
referenced them) are dropped. Test counts after absorption:
shipper 824 + shipper-cli full suite all green; clippy clean.

Per docs/decrating-plan.md S6 Phase 2.
@EffortlessSteven EffortlessSteven force-pushed the feature/decrating-absorb-auth-full branch from d9321ef to f1b06f1 Compare April 15, 2026 06:29
@EffortlessSteven EffortlessSteven merged commit 35be5ca into main Apr 15, 2026
9 of 15 checks passed
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