Tag Pipelines vs Cargo workspace publish command

Hello, using the cargo ws crate, I understand to get it to run on anything other than master, you must pass in the flag --allow-branch <BRANCH-NAME>. I am trying to versoin and tag my crates to publish to a private registry in a gitlab tag pipeline, which is not pointing to a branch but a commit hash on main, essentially taking a screenshot of the source code at that point in time. I am trying to figure out how I can get it to run on the tag branches. It is incredibly important context that I am using Gitlab, which has a specific tag pipeline. I am currently getting this error for my publish-crate job:

 * tag               0.14.0     -> FETCH_HEAD
$ git checkout --detach "$CI_COMMIT_TAG"
HEAD is now at <commit> merge branch y into x
$ echo "Publishing crates for tag $CI_COMMIT_TAG"
Publishing crates for tag 0.14.0
$ cargo ws publish --yes --allow-branch '*'
error: not on a git branch
Cleaning up project directory and file based variables
00:01
ERROR: Job failed: exit code 1

And here is my template file for additional context:


stages:
  - package
  - release
  - lint
  - build
  - test

# note some of this is generic/anonymized
include:
  - component: rust component
    inputs:
      component-version-ref: my version ref
  - component: release component
    inputs:
      component-version-ref: my version ref

publish-crates:
  tags:
    - runner tag
  stage: release
  image:
    name: rust image
    entrypoint: ["entrypoint/"]
  rules:
    - if: $CI_COMMIT_TAG
    - when: never
  before_script:
    - git config --global --add safe.directory "$(pwd)"
    - git config user.name "$GITLAB_USER_NAME"
    - git config user.email "$GITLAB_USER_EMAIL"
    - git remote set-url origin "https://__token__:$TOKEN@$CI_SERVER_HOST/$CI_PROJECT_PATH.git"
    - git remote set-url --push origin "https://__token__:$TOKEN@$CI_SERVER_HOST/$CI_PROJECT_PATH.git"
    - git fetch origin "refs/tags/$CI_COMMIT_TAG"
    - git checkout --detach "$CI_COMMIT_TAG"
  script:
    - echo "Publishing crates for tag $CI_COMMIT_TAG"
    - cargo ws publish --yes --allow-branch '*'

I understand this may not be the best place to ask this question since it is so specific to an individual crate I am using but I thought this may have been experienced by someone else and thought I would reach out anyway. Thanks!

I’m not familiar with the third-party “cargo ws” command you are using, but are you aware that Cargo now has built-in support for publishing multiple crates, including all or part of a workspace?

This works better than older external tools that merely invoke cargo publish more than once, because it runs verification on all the packages together, so it can catch packaging errors before publishing any one package.

This ended up not being the solution for me, simply because it was recommended by a Rust team where I work to use cargo ws and follow already established patterns they had. If only those patterns included a solution to my problem...joking haha. I wanted to improve some of the things they had and this is a bit cleaner than previous efforts!

What I ended up doing was shimmying the job that writes to Cargo.toml to update versions etc between the job I already had from another component that generated the new version/$TAG and the job that published/pushed to git and triggered the Gitlab tag pipeline(- cargo ws version --no-global-tag --no-individual-tags --allow-branch "$CI_DEFAULT_BRANCH" -y custom "$TAG"). I did this without manipulating the component that I was including, which is really awesome because it just emphasizes how customizable our infrastructure is working out to be. Then in the Gitlab tag pipeline, I used the specific flags --no-git-tag and --publish-as-is to get it to our private crate registry.

That portion is part of the Rust component that I have been working on, but because of the timing of the Release component jobs, the teams using the pipelines will have to do this template with the one job being in the .gitlab-ci.yml and the two components included. Overall not too terrible I wish that there was a way to make it just a template with two includes rather than an additional job but without changing the Release component I do not think that this is possible. Since the Release component is used for all Releases (anything from JS to C++) it is pretty broad.

It is a bit hacky, and there are definitely certain reason why we are doing things this way with multi pipelines for a single release/merge into main that are irrelevant to this discussion. But thought that I would follow up with my solution in case anyone else runs into a similar issue (but maybe it will only ever be me).

Here is the specific third party documentation, for anyone curious: crates.io: Rust Package Registry