repo-init/repo-add clone https repos with shared defaults.git credentials from ~/.werkator.yml via one-shot GIT_ASKPASS
93 lines
3.7 KiB
Markdown
93 lines
3.7 KiB
Markdown
> **WARNING:** This document describes only the change applied in this PR.
|
|
> It may already be outdated once the next PR is merged.
|
|
> Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation.
|
|
|
|
## Related Links
|
|
|
|
- ADR 0009 — multi-repo instance: the `defaults` block carries shared repository-level keys, read by `ConfigLoader`, never directly by consumers.
|
|
- `docs/deployment.md` — registry setup: `repo-add` clones, initialises, and prints the registry entry.
|
|
|
|
## The Problem
|
|
|
|
`tools/remote werkator repo-add <private-https-url>` fails on the host with `could not read Username`.
|
|
The clone runs anonymously, but the credentials exist only in the instance file's `defaults.git` block — which the script never consults.
|
|
Registering a private repository therefore needs a manual SSH session today.
|
|
|
|
## Non-Goals
|
|
|
|
The script still does not write `~/.werkator.yml`: registering stays the operator's decision.
|
|
No SSH-URL support: the forge is reached over `https` from the host.
|
|
No new config keys: `defaults.git.account`/`defaults.git.token` already exist.
|
|
|
|
## The Scenarios
|
|
|
|
### Feature: authenticated clone for private origins
|
|
|
|
#### Background
|
|
|
|
- The shared credentials live in `~/.werkator.yml` under `defaults.git` (ADR 0009).
|
|
- Public origins and instances without shared credentials must keep cloning anonymously.
|
|
|
|
#### Scenario#000.01: Private https origin clones with shared credentials
|
|
|
|
- **Given** `defaults.git.account`/`defaults.git.token` in `~/.werkator.yml` on the host
|
|
- **When** `tools/remote werkator repo-add <private-https-url>` runs
|
|
- **Then** the clone authenticates with those credentials and succeeds.
|
|
|
|
##### Verified by
|
|
|
|
- Manual stub-`git` test: URL carries `account@`, askpass answers the token, `GIT_TERMINAL_PROMPT=0`.
|
|
|
|
#### Scenario#000.02: Public origin clones anonymously
|
|
|
|
- **Given** no shared credentials (or a public repository)
|
|
- **When** `repo-add` or `repo-init` runs
|
|
- **Then** the clone runs exactly as before, without authentication.
|
|
|
|
##### Verified by
|
|
|
|
- Local helper test against a `file://` origin with and without an instance file.
|
|
|
|
#### Scenario#000.03: Token never leaks locally
|
|
|
|
- **Given** an authenticated clone
|
|
- **When** the command runs from the workstation
|
|
- **Then** the token appears in neither the local process list nor a repository config.
|
|
|
|
##### Verified by
|
|
|
|
- Code inspection: the token is read on the host and passed via a one-shot `GIT_ASKPASS` script.
|
|
|
|
## The Solution
|
|
|
|
`tools/remote` gained a `clone_repo` helper used by both `repo-init` and `repo-add`.
|
|
For `https://` URLs it ships a small Python helper (base64-encoded, so no `$` is expanded locally) to the host.
|
|
The helper reads `defaults.git.account`/`defaults.git.token` from `~/.werkator.yml`, puts the account into the URL, and hands the token to git via a one-shot `0700` `GIT_ASKPASS` script deleted in `finally`.
|
|
Without credentials it falls back to the plain anonymous clone; non-`https` URLs clone unchanged.
|
|
`docs/deployment.md` documents that the shared credentials must exist before cloning a private repository.
|
|
|
|
## Open Questions
|
|
|
|
- None.
|
|
|
|
## Attachments
|
|
|
|
### Adding a Gitea repository — example
|
|
|
|
From the workstation, clone and initialise, then register:
|
|
|
|
```bash
|
|
tools/remote --env-file .env.<instance> werkator repo-add https://gitea.example.org/<owner>/<repo>.git [<name>]
|
|
```
|
|
|
|
Add the printed entry to `~/.werkator.yml` under `repositories:`, then restart the service.
|
|
A public repository needs nothing else: the clone runs anonymously.
|
|
A private repository needs shared credentials once on the host, in `~/.werkator.yml` of the service user, before cloning (token: Gitea → Settings → Applications → Generate Token, scope `read:repository`):
|
|
|
|
```yaml
|
|
defaults:
|
|
git:
|
|
account: <gitea-user>
|
|
token: <token>
|
|
```
|