Extract revision/tag of git dependency from cargo

i have the following setup:

  • git repo A (hosted on GitHub) contains two crates: a library and a binary
  • git repo B (also hosted on GitHub):
    • depends on the library of repo A
    • needs to use the binary from repo A in its GitHub workflow and needs to have the same revision of the binary as it uses for the library

these repos are private, accordingly i cannot cargo-publish them to crates.io (and there's no private artefact server available where this is being used). but even if it were released there would still be the issue of grabbing the correct version.

the "easy" (quick-win) option is to just hard-code the version of repo A in two places: the tag of the git dependency in Cargo.toml and in the script which downloads the binary.
but: this will obviously lead to the two running out of sync since somebody will forget to update it in one of the two places. so i'd instead like to extract the tag of the dependency from cargo.
the next quick-win would be to just download the artefact from the latest release, but then i'd run into issues whenever i release a new version of repo A but haven't updated repo B yet.

what's the best way to achieve this?

i've found cargo-metadata which gives me a JSON. i guess i could use jq to try and extract the source of the library from repo A being pulled in as a dependency? and then i'd have to do some string-mangling to extract the tag from that?

is there an easier/cleaner way to achieve this? i was hoping that there's maybe a cargo command which could give me that information, something along the lines of the (imaginary) cargo show-dependency foo-lib --source which would give me a structured (e.g. JSON) source information just for that one foo-lib dependency where i could grab a git: tag: v1.0.0 information easily (again e.g. using jq).

thanks!

You could add repo A as a git submodule of repo B, then use path dependencies and cargo install --path A.

1 Like

thanks for your suggestion!
i forgot to mention this: i had initially started out with git submodules, but that led to another problem since i then added the library from repo A to the cargo workspace in repo B which in turn broke GitHub dependabot (since it didn't have the correct token to be able to clone the submodule, accordingly the workspace contained a reference to a non-existent crate).

i guess i could use a git submodule and just not add it to the workspace (and only use it as a path dependency), but that'd also feel a bit weird?

accessing private GitHub repo as Cargo git dependency in a workflow

using a git dependency for a private repo was surprisingly easy once you learn that you need to use HTTPS URLs and then add this step:

      - name: Set up credentials to access private GH repos in cargo dependencies
        run: echo -e "machine github.com\nlogin ${{ secrets.TOKEN_USERNAME }}\npassword ${{ secrets.TOKEN }}" > ~/.netrc

(i found this solution online, though i can't find the link for it right now)

Well, what I would do in this situation is just scrape the tag out of the Cargo.toml file — not looking at it as the general case “learn dependency information from Cargo” but “simplest thing that lets me not write this in my project twice”; perhaps extracting it with the toml library if I already have an xtask package.

It looks like you need Cargo.lock that also works for installation of a binary.

Cargo will add bin dependencies eventually.

For now, you could try to get the version from Cargo.lock yourself for installing the binary.