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

Check Cargo.lock in version control for libraries #8728

Closed
tiziano88 opened this issue Sep 24, 2020 · 45 comments · Fixed by #12382
Closed

Check Cargo.lock in version control for libraries #8728

tiziano88 opened this issue Sep 24, 2020 · 45 comments · Fixed by #12382
Labels
A-documenting-cargo-itself Area: Cargo's documentation C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` disposition-merge FCP with intent to merge finished-final-comment-period FCP complete S-needs-team-input Status: Needs input from team on whether/how to proceed. T-cargo Team: Cargo

Comments

@tiziano88
Copy link

tiziano88 commented Sep 24, 2020

Describe the problem you are trying to solve

The official FAQ and various other places strongly suggest (almost mandate) that libraries do not check in Cargo.lock. This serves so that if the library is used as a dependency from another crate, the parent crate should get to decide what particular versions of dependencies to use for itself and all its transitive dependencies, respecting versioning restrictions indicated in the relevant Cargo.toml files.

Describe the solution you'd like

  • strongly suggest versioning Cargo.lock in version control even for libraries; without this, it is practically impossible to achieve reproducibility of builds, tests and CI pipelines: the same exact version (commit checksum) of a library may compile / pass at some point in time on someone's machine, but spuriously break / fail later on or on some other machine, just because some dependency published a new version on crates.io
  • add an option to cargo to skip packaging the local Cargo.lock when publishing a library to crates.io (by default it will exclude it for libraries and include it for binaries)
    • perhaps it is sufficient to manually exclude Cargo.lock from a package until this is implemented
  • suggest relying on https://dependabot.com/rust/ or manually bumping dependencies in order to detect incompatibilities with new version of dependent crates in an automated way that is tracked under version control and maintains the hermeticity and reproducibility of builds, even for libraries

Notes

@tiziano88 tiziano88 added the C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` label Sep 24, 2020
@Eh2406
Copy link
Contributor

Eh2406 commented Sep 25, 2020

Just to be clere a libraries Cargo.lock has no effect on resolution for a project that depends on that library. That is true if the library does not commit its Cargo.lock, and it is true if it commits it but does not include it when publishing, and it is true even if it ends up in the final published artifact. If you commit your Cargo.lock, so your CI is not broken by some new version on crates.io, then the first you will hear about the brokege is from your users.

Whether it is better to have flakey but real test in CI or to have reliable but mocked tests in CI, really depends on the priorities of the library. It is not so different from every other time a project considers using mock objects. Do you call that other microservice, then you will now fast if they broke their api but tests will be flakey, or do you mock it so you have fast reliable test of what that microservice used to respond.

@ehuss
Copy link
Contributor

ehuss commented Oct 20, 2020

I think it would be fine to add some more details to the documentation. There's a tradeoff, if Cargo.lock is included in source control, you'll likely be testing out-of-date dependencies. That's good for reproducibility as you say, but is bad because you won't quickly catch problems with new dependencies. If you have the CI budget, you can of course test both with Cargo.lock, and with the latest versions (by calling cargo update && cargo test).

@ehuss ehuss added the A-documenting-cargo-itself Area: Cargo's documentation label Oct 20, 2020
@tiziano88
Copy link
Author

Catching problems with new dependencies should not happen when someone is trying to test an unrelated change. Which often results in a new dependency breaking CI, which prevents even other, unrelated changes from going through.

dependabot (or something similar) seems the ideal solution to me, since it guarantees deterministic and hermetic CI, while at the same time allowing testing against new dependencies, in their own PR, so that if there is any issue after the fact it is also easy to narrow it down to the specific commit that introduced the new dependency version.

cargo update && cargo test has again reproducibility issues, since the result of cargo update depends on the exact point in time at which it is run.

@epage
Copy link
Contributor

epage commented Dec 26, 2022

Another reason to revisit this decision is interest in MSRV testing. Until we have a minimal versions resolver feature stablized, the lockfile is the easiest way to emulate it when verifying MSRV in libraries.

demurgos added a commit to demurgos/cargo that referenced this issue Jun 16, 2023
This commit updates the FAQ to recommend to always commit `Cargo.lock` in all projects, both binaries and libraries. The FAQ previously discouraged `Cargo.lock` in libraries.

The question of changing the recommendation to always commit the lock file was raised in rust-lang#8728, as well as in a few Rust Internals threads in the previous months ([Feedback of cargo-upgrade](https://internals.rust-lang.org/t/feedback-on-cargo-upgrade-to-prepare-it-for-merging/17101/124?u=demurgos), [Cargo yank is a misfeature](https://internals.rust-lang.org/t/suggestion-cargo-yank-is-a-misfeature-and-should-be-deprecated-and-eventually-removed/18486/15)) and was a relatively popular proposition.

`Cargo.lock` enables reproducible builds, I argue that this is a desirable property for _all_ projects. Reproducible builds are a safe and powerful default both for binaries and libraries. Wanting a non-reproducible build is less common, and still easy to achieve even if a lock file is committed.

Applications have binaries compiled through `cargo build` and executed by `cargo run`. Libraries also have binaries, they're just executed through `cargo test` instead. In both cases, it is desirable to be able to work with the version control system when debugging some regression. A `Cargo.lock` enables workflows such as `git bisect` or reproducing a failed test across all environments (e.g. CI and dev machines).

1. A lockfile enables reproducible builds across commits. This means that you can browse the git history and reproduce your tests as they were at this time. This unlocks `git bisect` workflow and is extremely useful when working on transitive dependency issues.

2. A lockfile ensures that you can reproduce an older build even if it contains  yanked dependencies or weakly constrained versions (semver requirement `*`, git repository without a revision, ...).

3. Even if a lock file is present, it is easy to refresh it / force dependency resolution again. On the other hand, if the lockfile is missing then it is very hard to retrieve the resolution at this time (or even impossible). Having a lock file is a safer default (no information loss).

4. When multiple developers contribute to the same project (even a library), a lock file ensures that all contributors test with the same dependencies. Without a lockfile, developers may see different behavior when testing. This also enables reproducing CI errors locally for example.

5. The usual objection to committing a lockfile is that it may take longer to detect regressions in transitive dependencies. In practice, this does not change much: refreshing the dependencies is always an explicit operation in Cargo anyway. The only time when it's done implicitly is when cloning a project for the first if it does not have a lock file yet. Checking transitive dependencies is better handled explicitly in CI or through tools such as Dependabot.

This change to always commit lock files also aligns with prior art from other ecosystems.
- [Yarn for Node.js](https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored)
  > Which files should be gitignored?
  >
  > [...]
  >
  > - yarn.lock should always be stored within your repository ([even if you develop a library](https://yarnpkg.com/getting-started/qa#should-lockfiles-be-committed-to-the-repository)).
- [Poetry for Python](https://python-poetry.org/docs/basic-usage/#committing-your-poetrylock-file-to-version-control)
  > As a library developer
  >
  > A simple way to avoid such a scenario is to omit the `poetry.lock` file. However, by doing so, you sacrifice reproducibility and performance to a certain extent. Without a lockfile, it can be difficult to find the reason for failing tests, because in addition to obvious code changes an unnoticed library update might be the culprit. [...]
  >
  > If you do not want to give up the reproducibility and performance benefits, consider a regular refresh of `poetry.lock` to stay up-to-date and reduce the risk of sudden breakage for users.
- [Bundler for Ruby](https://bundler.io/guides/faq.html#using-gemfiles-inside-gems)
  > Q: Should I commit my `Gemfile.lock` when writing a gem?
  >
  > A: Yes, you should commit it. The presence of a `Gemfile.lock` in a gem’s repository ensures that a fresh checkout of the repository uses the exact same set of dependencies every time. We believe this makes repositories more friendly towards new and existing contributors. Ideally, anyone should be able to clone the repo, run `bundle install`, and have passing tests. If you don’t check in your `Gemfile.lock`, new contributors can get different versions of your dependencies, and run into failing tests that they don’t know how to fix.

- Closes rust-lang#8728
demurgos added a commit to demurgos/cargo that referenced this issue Jun 16, 2023
This commit updates the FAQ to recommend to always commit `Cargo.lock` in all projects, both binaries and libraries. The FAQ previously discouraged `Cargo.lock` in libraries.

The question of changing the recommendation to always commit the lock file was raised in rust-lang#8728, as well as in a few Rust Internals threads in the previous months ([Feedback of cargo-upgrade](https://internals.rust-lang.org/t/feedback-on-cargo-upgrade-to-prepare-it-for-merging/17101/124?u=demurgos), [Cargo yank is a misfeature](https://internals.rust-lang.org/t/suggestion-cargo-yank-is-a-misfeature-and-should-be-deprecated-and-eventually-removed/18486/15)) and was a relatively popular proposition.

`Cargo.lock` enables reproducible builds, I argue that this is a desirable property for _all_ projects. Reproducible builds are a safe and powerful default both for binaries and libraries. Wanting a non-reproducible build is less common, and still easy to achieve even if a lock file is committed.

Applications have binaries compiled through `cargo build` and executed by `cargo run`. Libraries also have binaries, they're just executed through `cargo test` instead. In both cases, it is desirable to be able to work with the version control system when debugging some regression. A `Cargo.lock` enables workflows such as `git bisect` or reproducing a failed test across all environments (e.g. CI and dev machines).

1. A lockfile enables reproducible builds across commits. This means that you can browse the git history and reproduce your tests as they were at this time. This unlocks `git bisect` workflow and is extremely useful when working on transitive dependency issues.

2. A lockfile ensures that you can reproduce an older build even if it contains  yanked dependencies or weakly constrained versions (semver requirement `*`, git repository without a revision, ...).

3. Even if a lock file is present, it is easy to refresh it / force dependency resolution again. On the other hand, if the lockfile is missing then it is very hard to retrieve the resolution at this time (or even impossible). Having a lock file is a safer default (no information loss).

4. When multiple developers contribute to the same project (even a library), a lock file ensures that all contributors test with the same dependencies. Without a lockfile, developers may see different behavior when testing. This also enables reproducing CI errors locally for example.

5. The usual objection to committing a lockfile is that it may take longer to detect regressions in transitive dependencies. In practice, this does not change much: refreshing the dependencies is always an explicit operation in Cargo anyway. The only time when it's done implicitly is when cloning a project for the first if it does not have a lock file yet. Checking transitive dependencies is better handled explicitly in CI or through tools such as Dependabot.

This change to always commit lock files also aligns with prior art from other ecosystems.
- [Yarn for Node.js](https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored)
  > Which files should be gitignored?
  >
  > [...]
  >
  > - yarn.lock should always be stored within your repository ([even if you develop a library](https://yarnpkg.com/getting-started/qa#should-lockfiles-be-committed-to-the-repository)).
- [Poetry for Python](https://python-poetry.org/docs/basic-usage/#committing-your-poetrylock-file-to-version-control)
  > As a library developer
  >
  > A simple way to avoid such a scenario is to omit the `poetry.lock` file. However, by doing so, you sacrifice reproducibility and performance to a certain extent. Without a lockfile, it can be difficult to find the reason for failing tests, because in addition to obvious code changes an unnoticed library update might be the culprit. [...]
  >
  > If you do not want to give up the reproducibility and performance benefits, consider a regular refresh of `poetry.lock` to stay up-to-date and reduce the risk of sudden breakage for users.
- [Bundler for Ruby](https://bundler.io/guides/faq.html#using-gemfiles-inside-gems)
  > Q: Should I commit my `Gemfile.lock` when writing a gem?
  >
  > A: Yes, you should commit it. The presence of a `Gemfile.lock` in a gem’s repository ensures that a fresh checkout of the repository uses the exact same set of dependencies every time. We believe this makes repositories more friendly towards new and existing contributors. Ideally, anyone should be able to clone the repo, run `bundle install`, and have passing tests. If you don’t check in your `Gemfile.lock`, new contributors can get different versions of your dependencies, and run into failing tests that they don’t know how to fix.

Fixes rust-lang#8728
demurgos added a commit to demurgos/cargo that referenced this issue Jun 16, 2023
This commit updates the FAQ to recommend to always commit `Cargo.lock` in all projects, both binaries and libraries. The FAQ previously discouraged `Cargo.lock` in libraries.

The question of changing the recommendation to always commit the lock file was raised in rust-lang#8728, as well as in a few Rust Internals threads in the previous months ([Feedback of cargo-upgrade](https://internals.rust-lang.org/t/feedback-on-cargo-upgrade-to-prepare-it-for-merging/17101/124?u=demurgos), [Cargo yank is a misfeature](https://internals.rust-lang.org/t/suggestion-cargo-yank-is-a-misfeature-and-should-be-deprecated-and-eventually-removed/18486/15)) and was a relatively popular proposition.

`Cargo.lock` enables reproducible builds, I argue that this is a desirable property for _all_ projects. Reproducible builds are a safe and powerful default both for binaries and libraries. Wanting a non-reproducible build is less common, and still easy to achieve even if a lock file is committed.

Applications have binaries compiled through `cargo build` and executed by `cargo run`. Libraries also have binaries, they're just executed through `cargo test` instead. In both cases, it is desirable to be able to work with the version control system when debugging some regression. A `Cargo.lock` enables workflows such as `git bisect` or reproducing a failed test across all environments (e.g. CI and dev machines).

1. A lockfile enables reproducible builds across commits. This means that you can browse the git history and reproduce your tests as they were at this time. This unlocks `git bisect` workflow and is extremely useful when working on transitive dependency issues.

2. A lockfile ensures that you can reproduce an older build even if it contains  yanked dependencies or weakly constrained versions (semver requirement `*`, git repository without a revision, ...).

3. Even if a lock file is present, it is easy to refresh it / force dependency resolution again. On the other hand, if the lockfile is missing then it is very hard to retrieve the resolution at this time (or even impossible). Having a lock file is a safer default (no information loss).

4. When multiple developers contribute to the same project (even a library), a lock file ensures that all contributors test with the same dependencies. Without a lockfile, developers may see different behavior when testing. This also enables reproducing CI errors locally for example.

5. The usual objection to committing a lockfile is that it may take longer to detect regressions in transitive dependencies. In practice, this does not change much: refreshing the dependencies is always an explicit operation in Cargo anyway. The only time when it's done implicitly is when cloning a project for the first if it does not have a lock file yet. Checking transitive dependencies is better handled explicitly in CI or through tools such as Dependabot. Catching problems with new dependencies should not happen when someone is trying to test an unrelated change.

This change to always commit lock files also aligns with prior art from other ecosystems.
- [Yarn for Node.js](https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored)
  > Which files should be gitignored?
  >
  > [...]
  >
  > - yarn.lock should always be stored within your repository ([even if you develop a library](https://yarnpkg.com/getting-started/qa#should-lockfiles-be-committed-to-the-repository)).
- [Poetry for Python](https://python-poetry.org/docs/basic-usage/#committing-your-poetrylock-file-to-version-control)
  > As a library developer
  >
  > A simple way to avoid such a scenario [testing with latest transitive dependencies] is to omit the `poetry.lock` file. However, by doing so, you sacrifice reproducibility and performance to a certain extent. Without a lockfile, it can be difficult to find the reason for failing tests, because in addition to obvious code changes an unnoticed library update might be the culprit. [...]
  >
  > If you do not want to give up the reproducibility and performance benefits, consider a regular refresh of `poetry.lock` to stay up-to-date and reduce the risk of sudden breakage for users.
- [Bundler for Ruby](https://bundler.io/guides/faq.html#using-gemfiles-inside-gems)
  > Q: Should I commit my `Gemfile.lock` when writing a gem?
  >
  > A: Yes, you should commit it. The presence of a `Gemfile.lock` in a gem’s repository ensures that a fresh checkout of the repository uses the exact same set of dependencies every time. We believe this makes repositories more friendly towards new and existing contributors. Ideally, anyone should be able to clone the repo, run `bundle install`, and have passing tests. If you don’t check in your `Gemfile.lock`, new contributors can get different versions of your dependencies, and run into failing tests that they don’t know how to fix.

Fixes rust-lang#8728
demurgos added a commit to demurgos/cargo that referenced this issue Jun 16, 2023
This commit updates the FAQ to recommend to always commit `Cargo.lock` in all projects, both binaries and libraries. The FAQ previously discouraged `Cargo.lock` in libraries.

The question of changing the recommendation to always commit the lock file was raised in rust-lang#8728, as well as in a few Rust Internals threads in the previous months ([Feedback of cargo-upgrade](https://internals.rust-lang.org/t/feedback-on-cargo-upgrade-to-prepare-it-for-merging/17101/124?u=demurgos), [Cargo yank is a misfeature](https://internals.rust-lang.org/t/suggestion-cargo-yank-is-a-misfeature-and-should-be-deprecated-and-eventually-removed/18486/15)) and was a relatively popular proposition.

`Cargo.lock` enables reproducible builds, I argue that this is a desirable property for _all_ projects. Reproducible builds are a safe and powerful default both for binaries and libraries. Wanting a non-reproducible build is less common, and still easy to achieve even if a lock file is committed.

Applications have binaries compiled through `cargo build` and executed by `cargo run`. Libraries also have binaries, they're just executed through `cargo test` instead. In both cases, it is desirable to be able to work with the version control system when debugging some regression. A `Cargo.lock` enables workflows such as `git bisect` or reproducing a failed test across all environments (e.g. CI and dev machines).

1. A lockfile enables reproducible builds across commits. This means that you can browse the git history and reproduce your tests as they were at this time. This unlocks `git bisect` workflow and is extremely useful when working on transitive dependency issues.

2. A lockfile ensures that you can reproduce an older build even if it contains  yanked dependencies or weakly constrained versions (semver requirement `*`, git repository without a revision, ...).

3. Even if a lock file is present, it is easy to refresh it / force dependency resolution again. On the other hand, if the lockfile is missing then it is very hard to retrieve the resolution at this time (or even impossible). Having a lock file is a safer default (no information loss).

4. When multiple developers contribute to the same project (even a library), a lock file ensures that all contributors test with the same dependencies. Without a lockfile, developers may see different behavior when testing. This also enables reproducing CI errors locally for example.

5. The usual objection to committing a lockfile is that it may take longer to detect regressions in transitive dependencies. In practice, this does not change much: refreshing the dependencies is always an explicit operation in Cargo anyway. The only time when it's done implicitly is when cloning a project for the first if it does not have a lock file yet. Checking transitive dependencies is better handled explicitly in CI or through tools such as Dependabot. Catching problems with new dependencies should not happen when someone is trying to test an unrelated change.

This change to always commit lock files also aligns with prior art from other ecosystems.
- [Yarn for Node.js](https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored)
  > Which files should be gitignored?
  >
  > [...]
  >
  > - yarn.lock should always be stored within your repository ([even if you develop a library](https://yarnpkg.com/getting-started/qa#should-lockfiles-be-committed-to-the-repository)).
- [Poetry for Python](https://python-poetry.org/docs/basic-usage/#committing-your-poetrylock-file-to-version-control)
  > As a library developer
  >
  > A simple way to avoid such a scenario [testing with latest transitive dependencies] is to omit the `poetry.lock` file. However, by doing so, you sacrifice reproducibility and performance to a certain extent. Without a lockfile, it can be difficult to find the reason for failing tests, because in addition to obvious code changes an unnoticed library update might be the culprit. [...]
  >
  > If you do not want to give up the reproducibility and performance benefits, consider a regular refresh of `poetry.lock` to stay up-to-date and reduce the risk of sudden breakage for users.
- [Bundler for Ruby](https://bundler.io/guides/faq.html#using-gemfiles-inside-gems)
  > Q: Should I commit my `Gemfile.lock` when writing a gem?
  >
  > A: Yes, you should commit it. The presence of a `Gemfile.lock` in a gem’s repository ensures that a fresh checkout of the repository uses the exact same set of dependencies every time. We believe this makes repositories more friendly towards new and existing contributors. Ideally, anyone should be able to clone the repo, run `bundle install`, and have passing tests. If you don’t check in your `Gemfile.lock`, new contributors can get different versions of your dependencies, and run into failing tests that they don’t know how to fix.

Fixes rust-lang#8728
demurgos added a commit to demurgos/cargo that referenced this issue Jun 16, 2023
This commit updates the FAQ to recommend to always commit `Cargo.lock` in all projects, both binaries and libraries. The FAQ previously discouraged `Cargo.lock` in libraries.

The question of changing the recommendation to always commit the lock file was raised in rust-lang#8728, as well as in a few Rust Internals threads in the previous months ([Feedback of cargo-upgrade](https://internals.rust-lang.org/t/feedback-on-cargo-upgrade-to-prepare-it-for-merging/17101/124?u=demurgos), [Cargo yank is a misfeature](https://internals.rust-lang.org/t/suggestion-cargo-yank-is-a-misfeature-and-should-be-deprecated-and-eventually-removed/18486/15)) and was a relatively popular proposition.

`Cargo.lock` enables reproducible builds, I argue that this is a desirable property for _all_ projects. Reproducible builds are a safe and powerful default both for binaries and libraries. Wanting a non-reproducible build is less common, and still easy to achieve even if a lock file is committed.

Applications have binaries compiled through `cargo build` and executed by `cargo run`. Libraries also have binaries, they're just executed through `cargo test` instead. In both cases, it is desirable to be able to work with the version control system when debugging some regression. A `Cargo.lock` enables workflows such as `git bisect` or reproducing a failed test across all environments (e.g. CI and dev machines).

1. A lockfile enables reproducible builds across commits. This means that you can browse the git history and reproduce your tests as they were at this time. This unlocks `git bisect` workflow and is extremely useful when working on transitive dependency issues.

2. A lockfile ensures that you can reproduce an older build even if it contains  yanked dependencies or weakly constrained versions (semver requirement `*`, git repository without a revision, ...).

3. Even if a lock file is present, it is easy to refresh it / force dependency resolution again. On the other hand, if the lockfile is missing then it is very hard to retrieve the resolution at this time (or even impossible). Having a lock file is a safer default (no information loss).

4. When multiple developers contribute to the same project (even a library), a lock file ensures that all contributors test with the same dependencies. Without a lockfile, developers may see different behavior when testing. This also enables reproducing CI errors locally for example.

5. The usual objection to committing a lockfile is that it may take longer to detect regressions in transitive dependencies. In practice, this does not change much: refreshing the dependencies is always an explicit operation in Cargo anyway. The only time when it's done implicitly is when cloning a project for the first if it does not have a lock file yet. Checking transitive dependencies is better handled explicitly in CI or through tools such as Dependabot. Catching problems with new dependencies should not happen when someone is trying to test an unrelated change.

This change to always commit lock files also aligns with prior art from other ecosystems.
- [Yarn for Node.js](https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored)
  > Which files should be gitignored?
  >
  > [...]
  >
  > - yarn.lock should always be stored within your repository ([even if you develop a library](https://yarnpkg.com/getting-started/qa#should-lockfiles-be-committed-to-the-repository)).
- [Poetry for Python](https://python-poetry.org/docs/basic-usage/#committing-your-poetrylock-file-to-version-control)
  > As a library developer
  >
  > A simple way to avoid such a scenario [testing with latest transitive dependencies] is to omit the `poetry.lock` file. However, by doing so, you sacrifice reproducibility and performance to a certain extent. Without a lockfile, it can be difficult to find the reason for failing tests, because in addition to obvious code changes an unnoticed library update might be the culprit. [...]
  >
  > If you do not want to give up the reproducibility and performance benefits, consider a regular refresh of `poetry.lock` to stay up-to-date and reduce the risk of sudden breakage for users.
- [Bundler for Ruby](https://bundler.io/guides/faq.html#using-gemfiles-inside-gems)
  > Q: Should I commit my `Gemfile.lock` when writing a gem?
  >
  > A: Yes, you should commit it. The presence of a `Gemfile.lock` in a gem’s repository ensures that a fresh checkout of the repository uses the exact same set of dependencies every time. We believe this makes repositories more friendly towards new and existing contributors. Ideally, anyone should be able to clone the repo, run `bundle install`, and have passing tests. If you don’t check in your `Gemfile.lock`, new contributors can get different versions of your dependencies, and run into failing tests that they don’t know how to fix.

Fixes rust-lang#8728
@demurgos
Copy link
Contributor

I sent a PR to update the book and recommend always using a lock file: #12275

demurgos added a commit to demurgos/cargo that referenced this issue Jun 16, 2023
This commit updates the FAQ to recommend to always commit `Cargo.lock` in all projects, both binaries and libraries. The FAQ previously discouraged `Cargo.lock` in libraries.

The question of changing the recommendation to always commit the lock file was raised in rust-lang#8728, as well as in a few Rust Internals threads in the previous months ([Feedback of cargo-upgrade](https://internals.rust-lang.org/t/feedback-on-cargo-upgrade-to-prepare-it-for-merging/17101/124?u=demurgos), [Cargo yank is a misfeature](https://internals.rust-lang.org/t/suggestion-cargo-yank-is-a-misfeature-and-should-be-deprecated-and-eventually-removed/18486/15)) and was a relatively popular proposition.

`Cargo.lock` enables reproducible builds, I argue that this is a desirable property for _all_ projects. Reproducible builds are a safe and powerful default both for binaries and libraries. Wanting a non-reproducible build is less common, and still easy to achieve even if a lock file is committed.

Applications have binaries compiled through `cargo build` and executed by `cargo run`. Libraries also have binaries, they're just executed through `cargo test` instead. In both cases, it is desirable to be able to work with the version control system when debugging some regression. A `Cargo.lock` enables workflows such as `git bisect` or reproducing a failed test across all environments (e.g. CI and dev machines).

1. A lockfile enables reproducible builds across commits. This means that you can browse the git history and reproduce your tests as they were at this time. This unlocks `git bisect` workflow and is extremely useful when working on transitive dependency issues.

2. A lockfile ensures that you can reproduce an older build even if it contains  yanked dependencies or weakly constrained versions (semver requirement `*`, git repository without a revision, ...).

3. Even if a lock file is present, it is easy to refresh it / force dependency resolution again. On the other hand, if the lockfile is missing then it is very hard to retrieve the resolution at this time (or even impossible). Having a lock file is a safer default (no information loss).

4. When multiple developers contribute to the same project (even a library), a lock file ensures that all contributors test with the same dependencies. Without a lockfile, developers may see different behavior when testing. This also enables reproducing CI errors locally for example.

5. The usual objection to committing a lockfile is that it may take longer to detect regressions in transitive dependencies. In practice, this does not change much: refreshing the dependencies is always an explicit operation in Cargo anyway. The only time when it's done implicitly is when cloning a project for the first if it does not have a lock file yet. Checking transitive dependencies is better handled explicitly in CI or through tools such as Dependabot. Catching problems with new dependencies should not happen when someone is trying to test an unrelated change. There is also a magnitude more builds in consumer projects than CI builds for a lib, so you should be ready to get messaged by your users anyway if you break something :)

This change to always commit lock files also aligns with prior art from other ecosystems.
- [Yarn for Node.js](https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored)
  > Which files should be gitignored?
  >
  > [...]
  >
  > - yarn.lock should always be stored within your repository ([even if you develop a library](https://yarnpkg.com/getting-started/qa#should-lockfiles-be-committed-to-the-repository)).
- [Poetry for Python](https://python-poetry.org/docs/basic-usage/#committing-your-poetrylock-file-to-version-control)
  > As a library developer
  >
  > A simple way to avoid such a scenario [testing with latest transitive dependencies] is to omit the `poetry.lock` file. However, by doing so, you sacrifice reproducibility and performance to a certain extent. Without a lockfile, it can be difficult to find the reason for failing tests, because in addition to obvious code changes an unnoticed library update might be the culprit. [...]
  >
  > If you do not want to give up the reproducibility and performance benefits, consider a regular refresh of `poetry.lock` to stay up-to-date and reduce the risk of sudden breakage for users.
- [Bundler for Ruby](https://bundler.io/guides/faq.html#using-gemfiles-inside-gems)
  > Q: Should I commit my `Gemfile.lock` when writing a gem?
  >
  > A: Yes, you should commit it. The presence of a `Gemfile.lock` in a gem’s repository ensures that a fresh checkout of the repository uses the exact same set of dependencies every time. We believe this makes repositories more friendly towards new and existing contributors. Ideally, anyone should be able to clone the repo, run `bundle install`, and have passing tests. If you don’t check in your `Gemfile.lock`, new contributors can get different versions of your dependencies, and run into failing tests that they don’t know how to fix.

Fixes rust-lang#8728
demurgos added a commit to demurgos/cargo that referenced this issue Jun 16, 2023
This commit updates the FAQ to recommend to always commit `Cargo.lock` in all projects, both binaries and libraries. The FAQ previously discouraged `Cargo.lock` in libraries.

The question of changing the recommendation to always commit the lock file was raised in rust-lang#8728, as well as in a few Rust Internals threads in the previous months ([Feedback of cargo-upgrade](https://internals.rust-lang.org/t/feedback-on-cargo-upgrade-to-prepare-it-for-merging/17101/124?u=demurgos), [Cargo yank is a misfeature](https://internals.rust-lang.org/t/suggestion-cargo-yank-is-a-misfeature-and-should-be-deprecated-and-eventually-removed/18486/15)) and was a relatively popular proposition.

`Cargo.lock` enables reproducible builds, I argue that this is a desirable property for _all_ projects. Reproducible builds are a safe and powerful default both for binaries and libraries. Wanting a non-reproducible build is less common, and still easy to achieve even if a lock file is committed.

Applications have binaries compiled through `cargo build` and executed by `cargo run`. Libraries also have binaries, they're just executed through `cargo test` instead. In both cases, it is desirable to be able to work with the version control system when debugging some regression. A `Cargo.lock` enables workflows such as `git bisect` or reproducing a failed test across all environments (e.g. CI and dev machines).

1. A lockfile enables reproducible builds across commits. This means that you can browse the git history and reproduce your tests as they were at this time. This unlocks `git bisect` workflow and is extremely useful when working on transitive dependency issues.

2. A lockfile ensures that you can reproduce an older build even if it contains  yanked dependencies or weakly constrained versions (semver requirement `*`, git repository without a revision, ...).

3. Even if a lock file is present, it is easy to refresh it / force dependency resolution again. On the other hand, if the lockfile is missing then it is very hard to retrieve the resolution at this time (or even impossible). Having a lock file is a safer default (no information loss).

4. When multiple developers contribute to the same project (even a library), a lock file ensures that all contributors test with the same dependencies. Without a lockfile, developers may see different behavior when testing. This also enables reproducing CI errors locally for example.

5. The usual objection to committing a lockfile is that it may take longer to detect regressions in transitive dependencies. In practice, this does not change much: refreshing the dependencies is always an explicit operation in Cargo anyway. The only time when it's done implicitly is when cloning a project for the first if it does not have a lock file yet. Checking transitive dependencies is better handled explicitly in CI or through tools such as Dependabot. Catching problems with new dependencies should not happen when someone is trying to test an unrelated change. There is also a magnitude more builds in consumer projects than CI builds for a lib, so you should be ready to get messaged by your users anyway if you break something :)

This change to always commit lock files also aligns with prior art from other ecosystems.
- [Yarn for Node.js](https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored)
  > Which files should be gitignored?
  >
  > [...]
  >
  > - yarn.lock should always be stored within your repository ([even if you develop a library](https://yarnpkg.com/getting-started/qa#should-lockfiles-be-committed-to-the-repository)).
- [Poetry for Python](https://python-poetry.org/docs/basic-usage/#committing-your-poetrylock-file-to-version-control)
  > As a library developer
  >
  > A simple way to avoid such a scenario [testing with latest transitive dependencies] is to omit the `poetry.lock` file. However, by doing so, you sacrifice reproducibility and performance to a certain extent. Without a lockfile, it can be difficult to find the reason for failing tests, because in addition to obvious code changes an unnoticed library update might be the culprit. [...]
  >
  > If you do not want to give up the reproducibility and performance benefits, consider a regular refresh of `poetry.lock` to stay up-to-date and reduce the risk of sudden breakage for users.
- [Bundler for Ruby](https://bundler.io/guides/faq.html#using-gemfiles-inside-gems)
  > Q: Should I commit my `Gemfile.lock` when writing a gem?
  >
  > A: Yes, you should commit it. The presence of a `Gemfile.lock` in a gem’s repository ensures that a fresh checkout of the repository uses the exact same set of dependencies every time. We believe this makes repositories more friendly towards new and existing contributors. Ideally, anyone should be able to clone the repo, run `bundle install`, and have passing tests. If you don’t check in your `Gemfile.lock`, new contributors can get different versions of your dependencies, and run into failing tests that they don’t know how to fix.

Fixes rust-lang#8728
demurgos added a commit to demurgos/cargo that referenced this issue Jun 16, 2023
This commit updates the FAQ to recommend to always commit `Cargo.lock` in all projects, both binaries and libraries. The FAQ previously discouraged `Cargo.lock` in libraries.

The question of changing the recommendation to always commit the lock file was raised in rust-lang#8728, as well as in a few Rust Internals threads in the previous months ([Feedback of cargo-upgrade](https://internals.rust-lang.org/t/feedback-on-cargo-upgrade-to-prepare-it-for-merging/17101/124?u=demurgos), [Cargo yank is a misfeature](https://internals.rust-lang.org/t/suggestion-cargo-yank-is-a-misfeature-and-should-be-deprecated-and-eventually-removed/18486/15)) and was a relatively popular proposition.

`Cargo.lock` enables reproducible builds, I argue that this is a desirable property for _all_ projects. Reproducible builds are a safe and powerful default both for binaries and libraries. Wanting a non-reproducible build is less common, and still easy to achieve even if a lock file is committed.

Applications have binaries compiled through `cargo build` and executed by `cargo run`. Libraries also have binaries, they're just executed through `cargo test` instead. In both cases, it is desirable to be able to work with the version control system when debugging some regression. A `Cargo.lock` enables workflows such as `git bisect` or reproducing a failed test across all environments (e.g. CI and dev machines).

1. A lockfile enables reproducible builds across commits. This means that you can browse the git history and reproduce your tests as they were at this time. This unlocks `git bisect` workflow and is extremely useful when working on transitive dependency issues.

2. A lockfile ensures that you can reproduce an older build even if it contains  yanked dependencies or weakly constrained versions (semver requirement `*`, git repository without a revision, ...).

3. Even if a lock file is present, it is easy to refresh it / force dependency resolution again. On the other hand, if the lockfile is missing then it is very hard to retrieve the resolution at this time (or even impossible). Having a lock file is a safer default (no information loss).

4. When multiple developers contribute to the same project (even a library), a lock file ensures that all contributors test with the same dependencies. Without a lockfile, developers may see different behavior when testing. This also enables reproducing CI errors locally for example.

5. The usual objection to committing a lockfile is that it may take longer to detect regressions in transitive dependencies. In practice, this does not change much: refreshing the dependencies is always an explicit operation in Cargo anyway. The only time when it's done implicitly is when cloning a project for the first if it does not have a lock file yet. Checking transitive dependencies is better handled explicitly in CI or through tools such as Dependabot. Catching problems with new dependencies should not happen when someone is trying to test an unrelated change. There is also a magnitude more builds in consumer projects than CI builds for a lib, so you should be ready to get messaged by your users anyway if you break something :)

This change to always commit lock files also aligns with prior art from other ecosystems.
- [Yarn for Node.js](https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored)
  > Which files should be gitignored?
  >
  > [...]
  >
  > - yarn.lock should always be stored within your repository ([even if you develop a library](https://yarnpkg.com/getting-started/qa#should-lockfiles-be-committed-to-the-repository)).
- [Poetry for Python](https://python-poetry.org/docs/basic-usage/#committing-your-poetrylock-file-to-version-control)
  > As a library developer
  >
  > A simple way to avoid such a scenario [testing with latest transitive dependencies] is to omit the `poetry.lock` file. However, by doing so, you sacrifice reproducibility and performance to a certain extent. Without a lockfile, it can be difficult to find the reason for failing tests, because in addition to obvious code changes an unnoticed library update might be the culprit. [...]
  >
  > If you do not want to give up the reproducibility and performance benefits, consider a regular refresh of `poetry.lock` to stay up-to-date and reduce the risk of sudden breakage for users.
- [Bundler for Ruby](https://bundler.io/guides/faq.html#using-gemfiles-inside-gems)
  > Q: Should I commit my `Gemfile.lock` when writing a gem?
  >
  > A: Yes, you should commit it. The presence of a `Gemfile.lock` in a gem’s repository ensures that a fresh checkout of the repository uses the exact same set of dependencies every time. We believe this makes repositories more friendly towards new and existing contributors. Ideally, anyone should be able to clone the repo, run `bundle install`, and have passing tests. If you don’t check in your `Gemfile.lock`, new contributors can get different versions of your dependencies, and run into failing tests that they don’t know how to fix.

This commit also updates `cargo new` to no longer ignore `Cargo.lock`.

Fixes rust-lang#8728
demurgos added a commit to demurgos/cargo that referenced this issue Jun 16, 2023
This commit updates the FAQ to recommend to always commit `Cargo.lock` in all projects, both binaries and libraries. The FAQ previously discouraged `Cargo.lock` in libraries.

The question of changing the recommendation to always commit the lock file was raised in rust-lang#8728, as well as in a few Rust Internals threads in the previous months ([Feedback of cargo-upgrade](https://internals.rust-lang.org/t/feedback-on-cargo-upgrade-to-prepare-it-for-merging/17101/124?u=demurgos), [Cargo yank is a misfeature](https://internals.rust-lang.org/t/suggestion-cargo-yank-is-a-misfeature-and-should-be-deprecated-and-eventually-removed/18486/15)) and was a relatively popular proposition.

`Cargo.lock` enables reproducible builds, I argue that this is a desirable property for _all_ projects. Reproducible builds are a safe and powerful default both for binaries and libraries. Wanting a non-reproducible build is less common, and still easy to achieve even if a lock file is committed.

Applications have binaries compiled through `cargo build` and executed by `cargo run`. Libraries also have binaries, they're just executed through `cargo test` instead. In both cases, it is desirable to be able to work with the version control system when debugging some regression. A `Cargo.lock` enables workflows such as `git bisect` or reproducing a failed test across all environments (e.g. CI and dev machines).

1. A lockfile enables reproducible builds across commits. This means that you can browse the git history and reproduce your tests as they were at this time. This unlocks `git bisect` workflow and is extremely useful when working on transitive dependency issues.

2. A lockfile ensures that you can reproduce an older build even if it contains  yanked dependencies or weakly constrained versions (semver requirement `*`, git repository without a revision, ...).

3. Even if a lock file is present, it is easy to refresh it / force dependency resolution again. On the other hand, if the lockfile is missing then it is very hard to retrieve the resolution at this time (or even impossible). Having a lock file is a safer default (no information loss).

4. When multiple developers contribute to the same project (even a library), a lock file ensures that all contributors test with the same dependencies. Without a lockfile, developers may see different behavior when testing. This also enables reproducing CI errors locally for example.

5. The usual objection to committing a lockfile is that it may take longer to detect regressions in transitive dependencies. In practice, this does not change much: refreshing the dependencies is always an explicit operation in Cargo anyway. The only time when it's done implicitly is when cloning a project for the first if it does not have a lock file yet. Checking transitive dependencies is better handled explicitly in CI or through tools such as Dependabot. Catching problems with new dependencies should not happen when someone is trying to test an unrelated change. There is also a magnitude more builds in consumer projects than CI builds for a lib, so you should be ready to get messaged by your users anyway if you break something :)

This change to always commit lock files also aligns with prior art from other ecosystems.
- [Yarn for Node.js](https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored)
  > Which files should be gitignored?
  >
  > [...]
  >
  > - yarn.lock should always be stored within your repository ([even if you develop a library](https://yarnpkg.com/getting-started/qa#should-lockfiles-be-committed-to-the-repository)).
- [Poetry for Python](https://python-poetry.org/docs/basic-usage/#committing-your-poetrylock-file-to-version-control)
  > As a library developer
  >
  > A simple way to avoid such a scenario [testing with latest transitive dependencies] is to omit the `poetry.lock` file. However, by doing so, you sacrifice reproducibility and performance to a certain extent. Without a lockfile, it can be difficult to find the reason for failing tests, because in addition to obvious code changes an unnoticed library update might be the culprit. [...]
  >
  > If you do not want to give up the reproducibility and performance benefits, consider a regular refresh of `poetry.lock` to stay up-to-date and reduce the risk of sudden breakage for users.
- [Bundler for Ruby](https://bundler.io/guides/faq.html#using-gemfiles-inside-gems)
  > Q: Should I commit my `Gemfile.lock` when writing a gem?
  >
  > A: Yes, you should commit it. The presence of a `Gemfile.lock` in a gem’s repository ensures that a fresh checkout of the repository uses the exact same set of dependencies every time. We believe this makes repositories more friendly towards new and existing contributors. Ideally, anyone should be able to clone the repo, run `bundle install`, and have passing tests. If you don’t check in your `Gemfile.lock`, new contributors can get different versions of your dependencies, and run into failing tests that they don’t know how to fix.

This commit also updates `cargo new` to no longer ignore `Cargo.lock`.

Fixes rust-lang#8728
demurgos added a commit to demurgos/cargo that referenced this issue Jun 16, 2023
This commit updates the FAQ to recommend to always commit `Cargo.lock` in all projects, both binaries and libraries. The FAQ previously discouraged `Cargo.lock` in libraries.

The question of changing the recommendation to always commit the lock file was raised in rust-lang#8728, as well as in a few Rust Internals threads in the previous months ([Feedback of cargo-upgrade](https://internals.rust-lang.org/t/feedback-on-cargo-upgrade-to-prepare-it-for-merging/17101/124?u=demurgos), [Cargo yank is a misfeature](https://internals.rust-lang.org/t/suggestion-cargo-yank-is-a-misfeature-and-should-be-deprecated-and-eventually-removed/18486/15)) and was a relatively popular proposition.

`Cargo.lock` enables reproducible builds, I argue that this is a desirable property for _all_ projects. Reproducible builds are a safe and powerful default both for binaries and libraries. Wanting a non-reproducible build is less common, and still easy to achieve even if a lock file is committed.

Applications have binaries compiled through `cargo build` and executed by `cargo run`. Libraries also have binaries, they're just executed through `cargo test` instead. In both cases, it is desirable to be able to work with the version control system when debugging some regression. A `Cargo.lock` enables workflows such as `git bisect` or reproducing a failed test across all environments (e.g. CI and dev machines).

1. A lockfile enables reproducible builds across commits. This means that you can browse the git history and reproduce your tests as they were at this time. This unlocks `git bisect` workflow and is extremely useful when working on transitive dependency issues.

2. A lockfile ensures that you can reproduce an older build even if it contains  yanked dependencies or weakly constrained versions (semver requirement `*`, git repository without a revision, ...).

3. Even if a lock file is present, it is easy to refresh it / force dependency resolution again. On the other hand, if the lockfile is missing then it is very hard to retrieve the resolution at this time (or even impossible). Having a lock file is a safer default (no information loss).

4. When multiple developers contribute to the same project (even a library), a lock file ensures that all contributors test with the same dependencies. Without a lockfile, developers may see different behavior when testing. This also enables reproducing CI errors locally for example.

5. The usual objection to committing a lockfile is that it may take longer to detect regressions in transitive dependencies. In practice, this does not change much: refreshing the dependencies is always an explicit operation in Cargo anyway. The only time when it's done implicitly is when cloning a project for the first if it does not have a lock file yet. Checking transitive dependencies is better handled explicitly in CI or through tools such as Dependabot. Catching problems with new dependencies should not happen when someone is trying to test an unrelated change. There is also a magnitude more builds in consumer projects than CI builds for a lib, so you should be ready to get messaged by your users anyway if you break something :)

This change to always commit lock files also aligns with prior art from other ecosystems.
- [Yarn for Node.js](https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored)
  > Which files should be gitignored?
  >
  > [...]
  >
  > - yarn.lock should always be stored within your repository ([even if you develop a library](https://yarnpkg.com/getting-started/qa#should-lockfiles-be-committed-to-the-repository)).
- [Poetry for Python](https://python-poetry.org/docs/basic-usage/#committing-your-poetrylock-file-to-version-control)
  > As a library developer
  >
  > A simple way to avoid such a scenario [testing with latest transitive dependencies] is to omit the `poetry.lock` file. However, by doing so, you sacrifice reproducibility and performance to a certain extent. Without a lockfile, it can be difficult to find the reason for failing tests, because in addition to obvious code changes an unnoticed library update might be the culprit. [...]
  >
  > If you do not want to give up the reproducibility and performance benefits, consider a regular refresh of `poetry.lock` to stay up-to-date and reduce the risk of sudden breakage for users.
- [Bundler for Ruby](https://bundler.io/guides/faq.html#using-gemfiles-inside-gems)
  > Q: Should I commit my `Gemfile.lock` when writing a gem?
  >
  > A: Yes, you should commit it. The presence of a `Gemfile.lock` in a gem’s repository ensures that a fresh checkout of the repository uses the exact same set of dependencies every time. We believe this makes repositories more friendly towards new and existing contributors. Ideally, anyone should be able to clone the repo, run `bundle install`, and have passing tests. If you don’t check in your `Gemfile.lock`, new contributors can get different versions of your dependencies, and run into failing tests that they don’t know how to fix.

This commit also updates `cargo new` to no longer ignore `Cargo.lock`.

Fixes rust-lang#8728
demurgos added a commit to demurgos/cargo that referenced this issue Jun 16, 2023
This commit updates the FAQ to recommend to always commit `Cargo.lock` in all projects, both binaries and libraries. The FAQ previously discouraged `Cargo.lock` in libraries.

The question of changing the recommendation to always commit the lock file was raised in rust-lang#8728, as well as in a few Rust Internals threads in the previous months ([Feedback of cargo-upgrade](https://internals.rust-lang.org/t/feedback-on-cargo-upgrade-to-prepare-it-for-merging/17101/124?u=demurgos), [Cargo yank is a misfeature](https://internals.rust-lang.org/t/suggestion-cargo-yank-is-a-misfeature-and-should-be-deprecated-and-eventually-removed/18486/15)) and was a relatively popular proposition.

`Cargo.lock` enables reproducible builds, I argue that this is a desirable property for _all_ projects. Reproducible builds are a safe and powerful default both for binaries and libraries. Wanting a non-reproducible build is less common, and still easy to achieve even if a lock file is committed.

Applications have binaries compiled through `cargo build` and executed by `cargo run`. Libraries also have binaries, they're just executed through `cargo test` instead. In both cases, it is desirable to be able to work with the version control system when debugging some regression. A `Cargo.lock` enables workflows such as `git bisect` or reproducing a failed test across all environments (e.g. CI and dev machines).

1. A lockfile enables reproducible builds across commits. This means that you can browse the git history and reproduce your tests as they were at this time. This unlocks `git bisect` workflow and is extremely useful when working on transitive dependency issues.

2. A lockfile ensures that you can reproduce an older build even if it contains  yanked dependencies or weakly constrained versions (semver requirement `*`, git repository without a revision, ...).

3. Even if a lock file is present, it is easy to refresh it / force dependency resolution again. On the other hand, if the lockfile is missing then it is very hard to retrieve the resolution at this time (or even impossible). Having a lock file is a safer default (no information loss).

4. When multiple developers contribute to the same project (even a library), a lock file ensures that all contributors test with the same dependencies. Without a lockfile, developers may see different behavior when testing. This also enables reproducing CI errors locally for example.

5. The usual objection to committing a lockfile is that it may take longer to detect regressions in transitive dependencies. In practice, this does not change much: refreshing the dependencies is always an explicit operation in Cargo anyway. The only time when it's done implicitly is when cloning a project for the first if it does not have a lock file yet. Checking transitive dependencies is better handled explicitly in CI or through tools such as Dependabot. Catching problems with new dependencies should not happen when someone is trying to test an unrelated change. There is also a magnitude more builds in consumer projects than CI builds for a lib, so you should be ready to get messaged by your users anyway if you break something :)

This change to always commit lock files also aligns with prior art from other ecosystems.
- [Yarn for Node.js](https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored)
  > Which files should be gitignored?
  >
  > [...]
  >
  > - yarn.lock should always be stored within your repository ([even if you develop a library](https://yarnpkg.com/getting-started/qa#should-lockfiles-be-committed-to-the-repository)).
- [Poetry for Python](https://python-poetry.org/docs/basic-usage/#committing-your-poetrylock-file-to-version-control)
  > As a library developer
  >
  > A simple way to avoid such a scenario [testing with latest transitive dependencies] is to omit the `poetry.lock` file. However, by doing so, you sacrifice reproducibility and performance to a certain extent. Without a lockfile, it can be difficult to find the reason for failing tests, because in addition to obvious code changes an unnoticed library update might be the culprit. [...]
  >
  > If you do not want to give up the reproducibility and performance benefits, consider a regular refresh of `poetry.lock` to stay up-to-date and reduce the risk of sudden breakage for users.
- [Bundler for Ruby](https://bundler.io/guides/faq.html#using-gemfiles-inside-gems)
  > Q: Should I commit my `Gemfile.lock` when writing a gem?
  >
  > A: Yes, you should commit it. The presence of a `Gemfile.lock` in a gem’s repository ensures that a fresh checkout of the repository uses the exact same set of dependencies every time. We believe this makes repositories more friendly towards new and existing contributors. Ideally, anyone should be able to clone the repo, run `bundle install`, and have passing tests. If you don’t check in your `Gemfile.lock`, new contributors can get different versions of your dependencies, and run into failing tests that they don’t know how to fix.

This commit also updates `cargo new` to no longer ignore `Cargo.lock`.

Fixes rust-lang#8728
@epage epage added the S-needs-team-input Status: Needs input from team on whether/how to proceed. label Jun 17, 2023
demurgos added a commit to demurgos/cargo that referenced this issue Jun 17, 2023
This commit updates the FAQ to recommend to always commit `Cargo.lock` in all projects, both binaries and libraries. The FAQ previously discouraged `Cargo.lock` in libraries.

The question of changing the recommendation to always commit the lock file was raised in rust-lang#8728, as well as in a few Rust Internals threads in the previous months ([Feedback of cargo-upgrade](https://internals.rust-lang.org/t/feedback-on-cargo-upgrade-to-prepare-it-for-merging/17101/124?u=demurgos), [Cargo yank is a misfeature](https://internals.rust-lang.org/t/suggestion-cargo-yank-is-a-misfeature-and-should-be-deprecated-and-eventually-removed/18486/15)) and was a relatively popular proposition.

`Cargo.lock` enables reproducible builds, I argue that this is a desirable property for _all_ projects. Reproducible builds are a safe and powerful default both for binaries and libraries. Wanting a non-reproducible build is less common, and still easy to achieve even if a lock file is committed.

Applications have binaries compiled through `cargo build` and executed by `cargo run`. Libraries also have binaries, they're just executed through `cargo test` instead. In both cases, it is desirable to be able to work with the version control system when debugging some regression. A `Cargo.lock` enables workflows such as `git bisect` or reproducing a failed test across all environments (e.g. CI and dev machines).

1. A lockfile enables reproducible builds across commits. This means that you can browse the git history and reproduce your tests as they were at this time. This unlocks `git bisect` workflow and is extremely useful when working on transitive dependency issues.

2. A lockfile ensures that you can reproduce an older build even if it contains  yanked dependencies or weakly constrained versions (semver requirement `*`, git repository without a revision, ...).

3. Even if a lock file is present, it is easy to refresh it / force dependency resolution again. On the other hand, if the lockfile is missing then it is very hard to retrieve the resolution at this time (or even impossible). Having a lock file is a safer default (no information loss).

4. When multiple developers contribute to the same project (even a library), a lock file ensures that all contributors test with the same dependencies. Without a lockfile, developers may see different behavior when testing. This also enables reproducing CI errors locally for example.

5. The usual objection to committing a lockfile is that it may take longer to detect regressions in transitive dependencies. In practice, this does not change much: refreshing the dependencies is always an explicit operation in Cargo anyway. The only time when it's done implicitly is when cloning a project for the first if it does not have a lock file yet. Checking transitive dependencies is better handled explicitly in CI or through tools such as Dependabot. Catching problems with new dependencies should not happen when someone is trying to test an unrelated change. There is also a magnitude more builds in consumer projects than CI builds for a lib, so you should be ready to get messaged by your users anyway if you break something :)

This change to always commit lock files also aligns with prior art from other ecosystems.
- [Yarn for Node.js](https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored)
  > Which files should be gitignored?
  >
  > [...]
  >
  > - yarn.lock should always be stored within your repository ([even if you develop a library](https://yarnpkg.com/getting-started/qa#should-lockfiles-be-committed-to-the-repository)).
- [Poetry for Python](https://python-poetry.org/docs/basic-usage/#committing-your-poetrylock-file-to-version-control)
  > As a library developer
  >
  > A simple way to avoid such a scenario [testing with latest transitive dependencies] is to omit the `poetry.lock` file. However, by doing so, you sacrifice reproducibility and performance to a certain extent. Without a lockfile, it can be difficult to find the reason for failing tests, because in addition to obvious code changes an unnoticed library update might be the culprit. [...]
  >
  > If you do not want to give up the reproducibility and performance benefits, consider a regular refresh of `poetry.lock` to stay up-to-date and reduce the risk of sudden breakage for users.
- [Bundler for Ruby](https://bundler.io/guides/faq.html#using-gemfiles-inside-gems)
  > Q: Should I commit my `Gemfile.lock` when writing a gem?
  >
  > A: Yes, you should commit it. The presence of a `Gemfile.lock` in a gem’s repository ensures that a fresh checkout of the repository uses the exact same set of dependencies every time. We believe this makes repositories more friendly towards new and existing contributors. Ideally, anyone should be able to clone the repo, run `bundle install`, and have passing tests. If you don’t check in your `Gemfile.lock`, new contributors can get different versions of your dependencies, and run into failing tests that they don’t know how to fix.

This commit also updates `cargo new` to no longer ignore `Cargo.lock`.

Fixes rust-lang#8728
@epage
Copy link
Contributor

epage commented Jun 27, 2023

Wanted to add on some more data points around MSRV.

We've seen some people misuse version requirements (rather than using a lock file) to make working with MSRV easier, including:

Apparently, the version requirement approach is common enough that its a top google search (haven't been able to find it myself)

Some quick Googling suggested that I could explicitly depend on half in my own Cargo.toml, and therefore choose a compatible version there;

See https://www.reddit.com/r/rust/comments/14khqdt/is_there_something_different_about_cargos/

And I've noticed that for winnow that 16 out of 26 dependents exist for MSRV version req hacks. That number would be higher except I've specifically reached out to some of the dependents and tried to steer them to doing things a different way.

@epage
Copy link
Contributor

epage commented Jun 27, 2023

Motivations

  • Until MSRV-dependent dependency version resolution #9930, there is not a viable way of having a fixed-length-lookback MSRV (X number of releases)
  • Green master (local and CI)
    • Master failing for local development or a PR's CI from an unrelated change is a bad contributor experience
      • The contributor assumes its their fault and looks into it, wasting their time. Hopefully they recognize its not their fault. If they don't, then they waste even more time figuring out how their change broke it
      • Maintainers need to drop everything and fix it to not make the experience worse for contributors
      • This is delayed by (detection_time + report_time + maintainer_availability + fix_time + review_time + ci_time_pr + ci_time_bors)
    • Different lockfiles between different contributors is easy to overlook when dealing with "it works on my machine"
    • Example: Before cargo had its own lockfile, snapshot tests would fail when human readable output from a dependency changed, causing CI to go red
    • Example: Before cargo had its own lockfile, CI would turn red if a new dependency was released that deprecated parts of it API (Reduce warning strictness #10742 was also considered for resolving it)
    • Example: if -Zdirect-minimal-versions (Dependencies resolution with --minimal-versions #5657) is merged and people verify it, then a dependency updating a shared dependency can cause a breakage
    • Example: Not being broken by dependencies that yank versions (see also internals)
  • git bisect
    • Example: I had to bisect a problem with cargo but found no "root cause" commit. Most likely, the cause was in some dependency but I couldn't control for that
  • Documents a "golden stack" for debugging problems
  • If Cargo.lock represents minimal versions of dependencies (see also Dependencies resolution with --minimal-versions #5657), it can help developers relying on too-new APIs that will break when they get to CI
    • Ideally there would be a rustc or clippy lint to report API items with a #[stable] version that is newer than the minimal version that matches the dependency
  • If you start out with a lib and later turn it into a workspace with a bin, you are likely to overlook adding a lockfile

Downsides with having a policy of checking-in lockfiles

  • [lib]s CI jobs act as a distributed ecosystem-focused "crater" run. This puts peer pressure on the ecosystem for fixing bugs and yanking unintended breakages, helping maintain quality and adherence to semver.
    • Note that this is limited to [lib]-only repos that are following the guideline (e.g. clap checks in its lockfile) and only for releases that are semver compatible
  • Testing the latest dependencies reflects what dependents will be doing
    • This is also true for workspaces with [[bin]] crates ("cargo install" apparently ignores "Cargo.lock" as opposed to "cargo build" #7169) but isn't covered in the policy
    • This is only sampling dependencies at specific times and does not reflect if a dependent is locked to a version that wasn't not covered in CI or newer than the last CI run. Even worse is bugs can be dependent on the specific versions of dependencies and dependents.
  • To verify latest dependencies requires extra resources
  • Libraries might be running malware in their CI
    • At least for Github, Dependabot seems to run for security vulnerabilities even if its not otherwise enabled
  • Confusion over differences in lockfiles when dependents file bugs or contribute changes

Related questions:

  • What should Cargo.lock represent as opposed to Cargo.lock.<topic> if used?
    • Possibilities
      • Optimal dev environment (latest for features, fixes)
      • New dependent (latest)
      • MSRV
    • Larger lockfile upgrades make bisecting dependency problems harder
    • The newer the lockfile versions are (closer to latest), the more dependency versions that can be captured when bisecting an end-users issue
    • Juggling Cargo.lock.<topic> files can be a pain especially if there are specific policy constraints on what they may contain (MSRV compatible, minimal version, latest versions)
      • Extra work is needed to verify these in CI
      • A contributor likely won't know something is wrong until CI, requiring an extra round of iteration which is frustrating
      • The contributor would then need to cycle between the different lock files and make sure they get verified in the way that specific lockfile needs or delegate that to CI for extra turnaround time

Potential routes

  • MSRV-dependent dependency version resolution #9930 and Cargo time machine (generate lock files based on old registry state) #5221
  • Recommend maintaining a Cargo.lock.msrv
    • A CI job copies it into place and does verification with --locked (to ensure it isn't stale)
    • High friction for adding or changing dependencies
  • Change the Cargo.lock policy to check it in, updating cargo new to not exclude it in the .gitignore file
    • Recommend either staying up-to-date with dependencies (e.g. Dependabot or RenovateBot) or verify the latest dependencies always work with a job that runs cargo update before doing its verification (whether just cargo check or cargo test)
      • Automated dependency update allows people to choose their level of frequency, whether they want to be bleeding edge or play it safe and isolates the updates (and potential breakages) to PRs doing the update
      • The verification job should likely be a scheduled job to avoid making CI go red for contributors but Github will auto-disable the full Workflow for all Triggers if it is scheduled and there has been a lull in activity (2 months?), hurting projects that are passively maintained
    • Also recommend Lint to detect semantic versioning failures #374 once its available to reduce breaking of dependents
  • (exclusively for MSRV) Abandon an MSRV policy
  • (exclusively for MSRV) Change MSRV policy to be max-of-all-dependencies-at-current-moment
  • (exclusively for MSRV) Limit dependencies to only those that have the same MSRV policy or wider

See also a zulip thread from earlier this year

@epage
Copy link
Contributor

epage commented Jun 28, 2023

#12275 highlights the approach taken from other ecosystems

  • Yarn for Node.js

    Which files should be gitignored?

    [...]

  • Poetry for Python

    As a library developer

    A simple way to avoid such a scenario [testing with latest transitive dependencies] is to omit the poetry.lock file. However, by doing so, you sacrifice reproducibility and performance to a certain extent. Without a lockfile, it can be difficult to find the reason for failing tests, because in addition to obvious code changes an unnoticed library update might be the culprit. [...]

    If you do not want to give up the reproducibility and performance benefits, consider a regular refresh of poetry.lock to stay up-to-date and reduce the risk of sudden breakage for users.

  • Bundler for Ruby

    Q: Should I commit my Gemfile.lock when writing a gem?

    A: Yes, you should commit it. The presence of a Gemfile.lock in a gem’s repository ensures that a fresh checkout of the repository uses the exact same set of dependencies every time. We believe this makes repositories more friendly towards new and existing contributors. Ideally, anyone should be able to clone the repo, run bundle install, and have passing tests. If you don’t check in your Gemfile.lock, new contributors can get different versions of your dependencies, and run into failing tests that they don’t know how to fix.

@epage
Copy link
Contributor

epage commented Jun 29, 2023

@zackw and I met during office hours to discuss their concerns over lockfiles.

This is going to be a rough recollection of the discussion that I'm hoping people find helpful.

There were bad experiences with lockfiles in other ecosystems

  • "I downloaded a thing; it doesn't work. I deleted the lockfile; now it works"
    • For example, the compilers having broken compatibility and new dependency versions are needed to work with the current compiler versions
  • Lockfiles affecting dependents in node
    • Someone locked a dependency on something that only used TLS 1.1 (which was no longer being supported by services)
  • How do we build trust with people who have used similar looking techniques, even if our approach is different?

From this came up a concern: Would cargo eventually follow node and have lockfiles from dependencies affect dependents?

Testing

  • Testing a lockfile only tests a specific version
    • Minimum version requirements might be wrong
    • Bugs might have happened outside of the locked version that won' be caught
  • Unfortunately, CI resources are limited (and we can't time travel to test future versions of dependencies), so the question is which combination of dependencies should be tested
  • At this point, this seems orthogonal to lockfiles (checking in tests one set, not checking-in just tests a different set though it does evolve over time)
  • If we make a change in our Cargo.lock recommendation, we'd likely also recommend in our CI section for people to have a CI job that first runs cargo update, so people test Cargo.lock + latest

"Dependanbot"-like bots

  • These cause extra work and most of it wouldn't be needed if lockfiles didn't exist (some of us would still want automation of upgrading across breaking releases)
  • For me, I've found RenovateBot took away most of the churn
  • I also see it beneficial to have PRs for updating the lockfile because I then get CI runs to verify the upgrade worked rather than unpredictable CI failures on unrelated PRs

"I add a dependency on foo and its failing. I go to contribute a fix to foo and I can't reproduce it"

  • Yes, for first-time contributors not having a lockfile checked-in produces fewer chances of confusion
  • However, if its your second time interacting with foo, you can have the opposite experience where your local Cargo.lock from last time can't reproduce a failure in CI for your PR
  • Ends up being a trade off of which experience you focus on (along with all of the other trade offs)

Is checking-in a lockfile for MSRV just a hack?

  • Mostly
  • I started checking in my lockfiles because I found there was no way to maintain my MSRV policy without doing so
  • Ideally MSRV-dependent dependency version resolution #9930 would make this need go-away but that is dependent on whether MSRV is set in dependencies
    • I'll also conservatively say its a year out from stable versions of Rust. Longer if we have problems getting good error messages

How is it with the experience with old, unmaintained Rust projects?

  • For dependents, the lockfile doesn't matter
  • For "CI running latest helps verify new dependencies", the point is moot because CI isn't being run
    • You could have scheduled jobs but at least for Github, they deactivate the entire workflow if it has a cron trigger
  • For forking the project, I've just updated dependencies as part of the cleanup and it hasn't been a big deal

L-M-Sherlock pushed a commit to open-spaced-repetition/fsrs-rs that referenced this issue Aug 26, 2023
* Add Cargo.lock

The presence of a lock file doesn't affect the versions that other crates
will use, and it ensures that tests in CI are reproducible. Rust currently
recommends not checking it in for libraries, but this appears to be about
to change:
rust-lang/cargo#8728

* Update to the latest Burn; pin to a specific commit

* Silence a clippy warning

https://rust-lang.github.io/rust-clippy/master/index.html#/single_range_in_vec_init
was triggering for lines like

  let rating = ratings.clone().slice([i..i + 1]).transpose();

I think the warning probably doesn't apply for this API.

* Fix a clippy warning

* Pin the Rust version

Allowing it to float will lead to future clippy breakages, as clippy
routinely adds extra checks in new updates.
bjorn3 added a commit to bjorn3/portable-simd that referenced this issue Aug 26, 2023
As of rust-lang/cargo#8728 it is now recommended to always check in
Cargo.lock. This will help with reproducability and will avoid the need
for cg_clif's build system to keep it's own copy of Cargo.lock for
vendoring. It will also allow tidy to run on the portable-simd
workspace.
bjorn3 added a commit to bjorn3/backtrace-rs that referenced this issue Aug 27, 2023
As of rust-lang/cargo#8728 it is now recommended to always check in
Cargo.lock. This will help with reproducability. It will also allow
tidy to run on the backtrace workspace.
@safinaskar
Copy link

This fiasco is possibly related: rust-lang/rust#113152 (comment) . Nearly all my binary projects created nearly May 2023 (assuming they have Cargo.lock) don't build anymore. Removing Cargo.lock fixes them

@parasyte
Copy link

parasyte commented Aug 30, 2023

@safinaskar That breakage is unrelated to Cargo.lock; it is caused by a change to the nightly compiler. You can either build with the latest stable compiler (as mentioned in a response to your comment on that ticket) or, more appropriately perhaps, pin your nightly version with a toolchain file to avoid those kinds of breaking changes in the future.

@Nemo157
Copy link
Member

Nemo157 commented Aug 30, 2023

(or try to apply pressure on crate authors to not silently opt their users into unstable breakage simply because they use a nightly compiler)

@epage
Copy link
Contributor

epage commented Aug 30, 2023

I agree with @Nemo157 that that was a bug in proc-macro2 to use nightly features without a users consent (usually a unstable or nightly feature flag).

@ctz
Copy link
Contributor

ctz commented Oct 4, 2023

suggest relying on https://dependabot.com/rust/

Note that dependabot uses the existence of Cargo.lock as a heuristic that a crate is an application. The behaviour seems not configurable, and by default means a library-with-a-lockfile will churn dependency versions forwards in the Cargo.toml.

ref: https://github.com/dependabot/dependabot-core/blob/81ca7cb1d8d016583834c4a632d8b78daec934a5/cargo/lib/dependabot/cargo/update_checker.rb#L111-L115

@Nemo157
Copy link
Member

Nemo157 commented Oct 4, 2023

This might be a good incentive to open an issue about having that configurable in dependabot, it's a big reason I don't use it on most of my repos.

@epage
Copy link
Contributor

epage commented Oct 4, 2023

The primary reason I switched to RenovateBot was to make dependency updating faster (dropped my monthly updates from taking a couple days to part of a day) but the greater control was a close second. For example, here is the config for clap

workingjubilee pushed a commit to rust-lang/backtrace-rs that referenced this issue Oct 6, 2023
As of rust-lang/cargo#8728 it is now recommended to always check in
Cargo.lock. This will help with reproducability. It will also allow
tidy to run on the backtrace workspace.
9999years added a commit to 9999years/safetensors that referenced this issue Apr 18, 2024
`Cargo.lock` files were added in huggingface#229 and then removed about a month
later in huggingface#253 (with the justification that "cargo.lock messes up
benchmarks").

Shortly after, the Rust project guidance was updated to encourage
committing lockfiles:

https://blog.rust-lang.org/2023/08/29/committing-lockfiles.html
https://doc.rust-lang.org/cargo/faq.html#why-have-cargolock-in-version-control
rust-lang/cargo#8728

Let's add the lockfiles back to make builds reproducible and
deterministic, especially for consumers of Python bindings.
stevensdavid added a commit to stevensdavid/prodzilla that referenced this issue Jun 10, 2024
It seems that the guidance used to be that Cargo.lock should be tracked
for binaries (like Prodzilla) but not for libraries. It should have been
 tracked from the start according to this guidance.

 Updated guidance is available at
 https://blog.rust-lang.org/2023/08/29/committing-lockfiles.html , where
 the new recommendation is to simply do what is best for the project but
 defualt to tracking Cargo.lock.

For Prodzilla, tracking Cargo.lock helps make the Docker and binary
builds reproducible so I believe that it is beneficial to this project.

Further reference:
- https://doc.rust-lang.org/nightly/cargo/faq.html#why-have-cargolock-in-version-control
- rust-lang/cargo#8728
codingupastorm pushed a commit to prodzilla/prodzilla that referenced this issue Jul 21, 2024
* chore: Fix clippy warnings

In order to clean the code up a bit, I fixed everything that `cargo
clippy` complained about. The warnings were of types:

- redundant field names in struct initialization
- unused imports
- `&String` being used instead of `&str`, fixing this saves a copy
- unnecessary `return` statements
- use of `or_insert_with` instead of `or_default` for constructing
  default values
- some references which are immediately dereferenced by the compiler
- unneeded late initializations before `match` expressions
- single-character string constants being used instead of a char
- module inception in `test_utils::test_utils`. I renamed the inner
  module to `probe_test_utils` to facilitate other types of test util
  modules being added to that parent module.

Hopefully this should make the code a little bit more idiomatic,
although I'm far from a Rust expert so take the changes with a grain of
salt.

* feat: Add root span to more deeply instrument stories

* chore: Move otel setup to otel module

* fix: Add nested spans

* feat: Switch to tokio-tracing with tracing_opentelemetry

* feat: Add support for specifying other files through CLI

* chore: Update RAM usage in README

The changes thus far have increased RAM usage from 8 to around 14 MB on
my machine when running the default `prozilla.yml`. Hopefully this isn't
too bad, if necessary I could probably profile where the memory usage is
coming from but I'm fairly certain it's from OpenTelemetry since there's
a proper pipeline going on now.

* chore: move otel resource init to module root

* feat: Otel metrics, pick exporters with env

Adds some basic OpenTelemetry metrics support using
tracing_opentelemetry as well as support for choosing between stdout and
otlp exporters for both traces and metrics using the standard
OpenTelemetry environment variable conventions. Both traces and metrics
are disabled if the corresponding environment variables are not set.

* feat: Support environment variable substitution

* feat: Add trace ID to alerts

* Revert "feat: Switch to tokio-tracing with tracing_opentelemetry"

This reverts commit 3bbb42d.

* fix: Fix broken test

* chore: Run cargo fmt on entire project

* chore: Add .git-blame-ignore-revs to hide chore commits

* feat: Add 'Matches' expectation which tests a regular expression

* feat: Set up OTLP HTTP, remove tracing-opentelemetry

* feat: Trim variables to support whitespace in substitutions

* chore: Refactor metrics

* fix: Add 0 to error metrics on success

This is done so that the error metrics are initialized for that
particular set of labels to 0. By doing this, any backend that receives
the data will receive a time series that starts at 0 instead of
eventually receiving a new time series that starts at 1 once the first
error arrives. In the latter case, a promql query for `rate` e.g. would
fail to detect the transition from 0 -> 1 as the transition is actually
from non-existant to 1.

* feat: Add support for Slack webhooks

* feat: Enable use of env vars globally in config

The previous implementation hooked in to the same substitution logic as
for step outputs and generated values. This had the consequence that it
would only apply during probes, and can not be used for other parts of
the configuration file such as webhook URLs.

This commit moves the enivronment variable substitution to the
configuration loading step of Prodzilla's initialization in order to
allow environment variables to be used anywhere in the configuration.

* feat: Add basic dockerfile

* feat: Add GHA to build and publish docker image

* fix: Support multiplatform build through QEMU

* chore: Track Cargo.lock

It seems that the guidance used to be that Cargo.lock should be tracked
for binaries (like Prodzilla) but not for libraries. It should have been
 tracked from the start according to this guidance.

 Updated guidance is available at
 https://blog.rust-lang.org/2023/08/29/committing-lockfiles.html , where
 the new recommendation is to simply do what is best for the project but
 defualt to tracking Cargo.lock.

For Prodzilla, tracking Cargo.lock helps make the Docker and binary
builds reproducible so I believe that it is beneficial to this project.

Further reference:
- https://doc.rust-lang.org/nightly/cargo/faq.html#why-have-cargolock-in-version-control
- rust-lang/cargo#8728

* fix: Add more build dependencies

* fix: Set prodzilla as docker entrypoint

* fix: Fix dockerfile

* fix: Make whitespace around env vars optional

* fix: Drastically simplify dockerfile

* chore: Add test to catch earlier bug with whitespace in env vars

* chore: Document slack_webhook parameter

* docs: Update feature roadmap

* chore: revert accidental change to TOC format

* docs: Document new features

* fix: Fix regression with missing parent span IDs

Previously, opentelemetry tracing wouldn't be initialized at all if an
exporter isn't configured. This leads to parent trace IDs not being
available. This commit re-introduces the earlier Prodzilla behvaiour of
including a parent trace ID which is propagated in outgoing web
requests even if the root spans aren't exported.

* fix: Vendor openssl to enable cross-compilation

* feat: Add release workflow

* chore: Only build docker image on tagged releases

* chore: Update package version to v0.0.3

* feat: Add musl build targets for Alpine Linux

* fix: Improve error message on missing config file

* chore: add missing space in readme

* fix: Correct error metrics for probes

* feat: Include error message in webhook alerts

* feat!: Remove slack_webhook config parameter and route based on url instead

* chore: Update package version to v0.0.4

* chore: Cleanup error unwrapping

* feat: Include status code and body in alerts, style Slack

* feat: Add support for marking steps as sensitive

This leads to logs and alerts being redacted so that the sensitive
response bodies aren't included.

* fix: Report span status on probe error

* chore: Remove unused import

* fix: escape newlines in logged bodies

* feat: Make request timeout configurable

* chore: Use tidier Option unwrapping

* fix: Remove openssl vendoring, binary builds

OpenSSL vendoring was causing issues with builds on Windows so I think
for now it's probably best to just remove it and the binary builds that
required it. This means that releases will no longer include
executables, but the Docker images are still published and the source
code can be compiled for the target platform by the user.

It might be worth revisiting binary builds in the future with static
linking, but I don't have the time (or the use-case at $WORK) to do that
at the moment and would like to avoid this being a blocker.
sboukortt added a commit to libjxl/jxl-rs that referenced this issue Sep 16, 2024
This is the new recommendation, per
rust-lang/cargo#12382. See also the discussion
at: rust-lang/cargo#8728
sboukortt added a commit to libjxl/jxl-rs that referenced this issue Sep 16, 2024
This is the new recommendation, per
rust-lang/cargo#12382. See also the discussion
at: rust-lang/cargo#8728
sboukortt added a commit to libjxl/jxl-rs that referenced this issue Sep 16, 2024
This is the new recommendation, per
rust-lang/cargo#12382. See also the discussion
at: rust-lang/cargo#8728
orhun added a commit to ratatui/ratatui that referenced this issue Oct 20, 2024
When kept up to date, this makes it possible to build any git version
with the same versions of crates that were used for any version, without
it, you can only use the current versions. This makes bugs in semver
compatible code difficult to detect.

The Cargo.lock file is not used by downstream consumers of the crate, so
it is safe to include it in the repository (and recommended by the Rust
docs).

See:
- https://doc.rust-lang.org/cargo/faq.html#why-have-cargolock-in-version-control
- https://blog.rust-lang.org/2023/08/29/committing-lockfiles.html
- rust-lang/cargo#8728

Co-authored-by: Orhun Parmaksız <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-documenting-cargo-itself Area: Cargo's documentation C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` disposition-merge FCP with intent to merge finished-final-comment-period FCP complete S-needs-team-input Status: Needs input from team on whether/how to proceed. T-cargo Team: Cargo
Projects
None yet