Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting level per crate in a workspace #461

Closed
mike-code opened this issue May 5, 2022 · 7 comments
Closed

Setting level per crate in a workspace #461

mike-code opened this issue May 5, 2022 · 7 comments
Labels
enhancement Improve the expected

Comments

@mike-code
Copy link

mike-code commented May 5, 2022

Lets have a single repo workspace with 3 crates as directories in that repository

❯ tree -L 1
.
├── Cargo.lock
├── Cargo.toml
├── release.toml
├── the-lib/
├── the-db/
└── the-cli/

the-lib and the-db are 0.1.0 while the-cli is 0.2.0. Now, I'm starting to use cargo release, so I manually run cargo release <LEVEL=release> and I'm left with 3 new tags. All good so far. Now it's time to make it automated as soon as a new release PR to the main is merged.

Due to the fact that (usually) the CI is per repository and not per directory (ie. crate), I need to have some generic flow that works depending on the conditions. Now the problem I faced is that when running cargo release in the root (ie. workspace) directory, I need to specify the LEVEL for all crates. However, what if the-lib introduced breaking API changes and I want to bump it's major (ie. 0.1.0->1.0.0) while the-cli (that depends on the-lib) should merely be bumped with minor 0.2.0->0.3.0 and at the same time have it's crates dependencies (ie. the-lib) updated from ^0.1.0 to ^1.0.0. the-db was not changed at all so I'd like to skip it's version bump completely (not even make it a patch) but I don't have a "skip" LEVEL and any other options will leave me with an unnecessary version bump or an error that I'm trying to publish an already published package.

Ideally (I think) the decision on what should be the bump level I'd like to leave to the person that introduced those changes. So if I was the one who changed the-lib that it is not backwards compatible anymore, I should also be the one to somehow store that information in the code (think: gitflow). Perhaps I could use per-crate release.toml for that?

Right now I'm thinking to use pre-release hooks but I still don't know what should those hooks do exactly to achieve my goal. Any suggestions? thanks!

@epage
Copy link
Collaborator

epage commented May 5, 2022

It sounds like you are wanting to run cargo release in a github action that is triggered by a PR being merged?

Say cargo-release supported per-crate levels, how do you see sending that information to cargo release?

@mike-code
Copy link
Author

It sounds like you are wanting to run cargo release in a github action that is triggered by a PR being merged?

Correct, more precisely in gitlab's CI, but yeah, some kind of CI/CD.

Say cargo-release supported per-crate levels, how do you see sending that information to cargo release?

Actually I'd like to stick with cargo release per workspace just as it is now, but I'd like to have a bit more fine-grained control over bump level so that if only one crate needs major bump then I don't have to bump major version for all other crates.

@mike-code
Copy link
Author

mike-code commented May 5, 2022

And as for how to achieve that -- I was thinking whether I could have a level = <LEVEL> in per-crate release.toml that overrides the CLI argument? wdyt

@epage
Copy link
Collaborator

epage commented May 5, 2022

If its in the release.toml, then its static. How would a user decide they need to do a major, minor, or patch release? Is it expected that that would be part of the release PR? Maybe just me but it feels a bit wrong to be tracking transient state in git and could lead to workflow bugs where people forget to update it and get the wrong release level.

@mike-code
Copy link
Author

Is it expected that that would be part of the release PR?

That's how I imagined it. A developer who, for example, breaks the public API, in the same commit changes the level = to major.

If its in the release.toml, then its static.

I see, release.toml was only a suggestion. It could as well be tackled by pre-release hooks but the information on which level shall be used for a crate can as well be taken from elsewhere.

I'm not saying it's by the book -- I just couldn't figure out a better way to do that. I imagine a release PR where two crates are updated at the same time (see OP above) where one must be bumped with major and the other one with minor, though I don't know how to configure cargo release to do that automatically. The CI cannot make the decision on its own so it has to be specified either by the developer or the PR maintainer.

Even if I configure the CI to run cargo release from within the crate directories and not the workspace directory (ie. twice in my example) then :

  1. I have to maintain the order manually to make sure that the-cli notices that the-lib version was bumped
  2. When the CI kicks in, it already must somehow know that I want it to bump major for the-lib and minor for the-cli.

I know that it might sounds like configuring the CD flow (ie. level) dynamically in the codebase itself is off, though that's how gitops approaches this kind of workflow and IMHO it's not that bad. After all the PR maintainer (approver) double checks that the version bump in the codebase, specified by the developer, is about right.

@epage
Copy link
Collaborator

epage commented May 5, 2022

That's how I imagined it. A developer who, for example, breaks the public API, in the same commit changes the level = to major.

Who is responsible for lowering it?

though that's how gitops approaches this kind of workflow

While I'm not fully versed in gitops, I assume gitops tends to focus on moving towards a fixed state and that actions are idempotent. Tracking the release level in a file does not qualify as idempotent.

Its a big smell when you have to rely on review and checklists for process safety. These should be baked into the process or are sytemic failures.

Without re-evaluating from the ground up how I would build what you are wanting but starting from where you are, what I think I would explore is tracking what the next version should be in absolute terms and not by level, maintaining a list of the release order and having a script that steps through it, doing the release for each crate only if the intended version isn't already released. I'd maybe have a tool where dev can say cargo bump major and if the local version isn't the next major version from what is published, it goes ahead and bumps the number so a developer doesn't have to think about what the next version should be but declares their intent. You could even use conventional-commit style commits to have a tool to make sure that a crate is bumped in each PR relative to what the commit type and breaking-status are (I emphasize "a" because cross-crate changes make it ambiguous which the status should apply to).

With all of that said, this seems like a fairly specialized use case that has problems that doesn't seem like supporting per-crate levels and a skip level justify the upfront implementation and associated complexity.

@epage epage added the enhancement Improve the expected label Oct 4, 2022
@epage
Copy link
Collaborator

epage commented Oct 14, 2022

#530 added a cargo release version subcommand for setting the version on a per-crate basis. #538 then made it so we could release these versions as-is. I think this is the route we'll be going for bumping per crate generally rather than complicate the command line or try to store transient information in a static file. We can see how this works out and iterate.

For doing things in actions, I recommend checking out #117, #119, and #528. I'm closing this as a mix of resolved and closing in favor of those issues.

@epage epage closed this as completed Oct 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improve the expected
Projects
None yet
Development

No branches or pull requests

2 participants