# gitlab-cargo-shim
[Example configuration][example-configuration]
Say goodbye to your Git dependencies, `gitlab-cargo-shim` is a stateless SSH server that serves crates like a standard Cargo registry but from a [GitLab package registry][gitlab-package-registry], allowing you to use your private dependencies like any other dependency. No more `git push --force`s breaking your builds & get proper versioning in one simple little binary.
Access controls work like they do in GitLab, builds are scoped to users - if they don't have permission to the dependency they can't build it, it's that simple.
Users are identified by their SSH keys from GitLab when connecting to the server and an [impersonation token][imp-token] will be generated for that run in order to pull available versions. Builds will insert their token as a username to the SSH server and the shim will use that to call the GitLab API.
To publish run `cargo package` and push the resulting `.crate` file to the GitLab package repository with a semver-compatible version string, to consume the package configure your `.cargo/config.toml` and `Cargo.toml` accordingly.
```toml
# .cargo/config.toml
[registries]
my-gitlab-project = { index = "ssh://gitlab-cargo-shim.local/my-gitlab-group/my-gitlab-project" }
# Cargo.toml
[dependencies]
my-crate = { version = "0.1", registry = "my-gitlab-project" }
```
In your CI build, setup a `before_script` step to replace the connection string with one containing the CI token:
```yaml
# .gitlab-ci.yml
before_script:
- sed -i "s/(gitlab-cargo-shim.local)/gitlab-ci-token:$GITLAB-CI-TOKEN@\1/" .cargo/config.toml
```
(or add the corresponding [environment variable][envvar])
To release your package from CI, add a new pipeline step:
```yaml
release-crate:
image: rust:1.62
stage: deploy
only: # release when a tag is pushed
- tags
before_script:
- cargo install cargo-get
- export CRATE_NAME=$(cargo get --name) CRATE_VERSION=$(cargo get version)
- export CRATE_FILE=${CRATE_NAME}-${CRATE_VERSION}.crate
script:
- cargo package
- cargo metadata --format-version 1 > metadata.json
- 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file target/package/${CRATE_FILE} "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${CRATE_NAME}/${CRATE_VERSION}/${CRATE_FILE}"'
- 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file metadata.json "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${CRATE_NAME}/${CRATE_VERSION}/metadata.json"'
```
It's that easy. Go forth and enjoy your newfound quality of life improvements, Rustacean.
[gitlab-package-registry]: https://docs.gitlab.com/ee/user/packages/package_registry/index.html
[imp-token]: https://docs.gitlab.com/ee/api/index.html#impersonation-tokens
[envvar]: https://doc.rust-lang.org/cargo/reference/registries.html#using-an-alternate-registry
[example-configuration]: https://github.com/w4/gitlab-cargo-shim/blob/main/config.toml