Environment variables and subprocess behaviour¶
Which environment variables does rtb-forge set?¶
| Variable | Set on | Value | Why |
|---|---|---|---|
RTB_VCS_GIT_TOKEN |
the git subprocess for authenticated clone, fetch, push |
the resolved secret | Carries the password to the inline credential helper without putting it in argv |
GIT_TERMINAL_PROMPT |
the git subprocess for clone, fetch, push |
0 |
Makes an auth failure exit non-zero immediately instead of blocking on a prompt |
Both are set on the child process only. Neither is read from or written to the parent process environment.
The name is RTB_VCS_GIT_TOKEN, not RTB_FORGE_GIT_TOKEN¶
The crate was renamed from rtb-vcs to rtb-forge at extraction from the
rust-tool-base monorepo. The variable name was deliberately left alone, because
it is part of the runtime contract with anything that inspects the subprocess
environment. Do not expect an RTB_FORGE_-prefixed alias; there is none.
You do not set this variable yourself. It is written by rtb-forge onto the
child process. Where your token comes from is decided by the CredentialRef
you attach to the options struct — see
Authenticate git operations.
GIT_TERMINAL_PROMPT is not set for checkout or commit¶
Only the three network operations set it. Repo::commit and Repo::checkout
inherit the parent environment unchanged, so if something in that environment
causes git to prompt, those calls can block. In a service, set
GIT_TERMINAL_PROMPT=0 process-wide.
What exactly does the credential helper do?¶
Authenticated operations pass this to git as -c credential.helper=<value>:
The snippet contains no secret — it reads one from the environment at the moment git asks. Three properties follow:
- The secret never appears in argv, so it is not visible in
psoutput. - The secret is never written to a temporary file or to
~/.git-credentials. - The helper is scoped to the single invocation via
-c; it does not modify any repository or global git config.
The username is hard-coded to x-access-token. That is GitHub's
personal-access-token convention, and GitLab and Gitea accept it for
token-based auth too. There is no configuration hook to change it. A forge that
requires a real username with a token cannot be authenticated through
Repo::clone / fetch / push; wrap the operation yourself.
Which git commands are run?¶
Exactly these, always with the repository directory (Repo::path()) as the
working directory, except clone which takes the destination as an argument:
| Method | Command |
|---|---|
clone (anonymous) |
none — pure gix |
clone (authenticated) |
git -c credential.helper=<helper> clone -- <url> <dst> |
fetch (anonymous) |
git fetch <remote> |
fetch (authenticated) |
git -c credential.helper=<helper> fetch <remote> |
checkout |
git checkout [--force] <revspec> |
commit |
git add -- <paths…>, then git commit -m <message>, then git rev-parse HEAD |
push (anonymous) |
git push <remote> <refspec> |
push (authenticated) |
git -c credential.helper=<helper> push <remote> <refspec> |
The -- separators on clone and add stop a URL or path beginning with -
being read as a flag.
Nothing runs through a shell — every command is spawned directly with
std::process::Command, so shell metacharacters in a URL, path, remote name or
refspec are not interpreted. The credential-helper string is a shell snippet,
but it is git that evaluates it, not rtb-forge.
stdout is captured and discarded except for git rev-parse HEAD, whose output
becomes the commit OID. stderr is captured, trimmed, and placed in the cause
field of the corresponding RepoError. A failing git command's stderr can
therefore end up in your logs — it will not contain the token, because the
token is only ever in the environment, but it may contain a repository URL.
Which HTTP headers do the release backends send?¶
Every REST backend builds its reqwest client the same way:
| Setting | Value |
|---|---|
https_only |
true |
User-Agent |
rtb-forge/<crate version> — for example rtb-forge/0.7.1 |
timeout |
timeout_seconds seconds, or unset when it is 0 |
Per-request headers:
| Backend | Auth header | Other |
|---|---|---|
| GitHub | Authorization: Bearer <token> |
Accept: application/vnd.github+json, X-GitHub-Api-Version: 2022-11-28; Accept: application/octet-stream on downloads |
| GitLab | PRIVATE-TOKEN: <token> |
Accept: application/json |
| Gitea / Codeberg | Authorization: token <token> |
Accept: application/json |
| Bitbucket | HTTP Basic, username + token |
Accept: application/json |
| Direct | Authorization: Bearer <token> |
— |
The auth header is only added when a token was passed to the factory (and, for
Bitbucket, only when username is also set). The private config key does not
affect this.
Is plain HTTP ever possible?¶
Not from configuration. Every parameter struct carries an
allow_insecure_base_url field, but it is #[serde(skip)], so no config file
— YAML, TOML, environment overlay — can set it. It exists so the crate's own
tests can point a provider at a local wiremock or testcontainer, and it does
two things when set in Rust code: builds the client without https_only, and
constructs URLs with the http:// scheme.
The GitHub backend additionally refuses any host that literally begins
http://, regardless of the flag.
Does anything read the ambient environment?¶
The release-provider slice reads nothing — no proxy variables of its own, no
token discovery, no config file lookup. reqwest applies its own defaults,
which include honouring the system proxy environment.
The git slice reads the environment only through the tools it invokes: gix
and git both resolve user.name, user.email, init.defaultBranch, proxy
settings and everything else from git's normal configuration cascade. Credential
resolution is delegated to rtb-credentials, whose CredentialRef may name
environment variables to read — that is your configuration, not this crate's.