vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Create the instance repository on init and list it normally
3e7c5e6797105f87fe593bb4c34743d3615ab598 · Keenan Nemetz · 1d ago · parent 6ce635a8
Create the instance repository on init and list it normally `vole admin init` now creates the configured instance repository with the starter tree and indexes it, so a new instance starts with it. The repository is no longer hidden from the home page or activity feed: it has the same pages, history, and settings as any other, and its visibility is its own. The Admin page's create button remains as the repair path for an instance that predates this, using the same starter tree from the instancerepo package.
forge/instance.go +40
| @@ -328,9 +328,49 @@ func InitAt(cfgPath string) (string, error) { | |||
| 328 | 328 | if _, err := secure.HardenFileIfExists(cfg.UsersDB()); err != nil { | |
| 329 | 329 | return "", err | |
| 330 | 330 | } | |
| 331 | if err := seedInstanceRepo(cfg); err != nil { | ||
| 332 | return "", err | ||
| 333 | } | ||
| 331 | 334 | return abs, nil | |
| 332 | 335 | } | |
| 333 | 336 | ||
| 337 | // seedInstanceRepo creates the configured instance repository during init and | ||
| 338 | // seeds its starter tree. It is idempotent: a repository that already has a | ||
| 339 | // commit is left exactly as it is, so `vole admin init` stays an upgrade path. | ||
| 340 | func seedInstanceRepo(cfg *config.Config) error { | ||
| 341 | name := strings.TrimSpace(cfg.InstanceRepo) | ||
| 342 | if name == "" { | ||
| 343 | return nil | ||
| 344 | } | ||
| 345 | acls, err := access.Open(cfg.UsersDB()) | ||
| 346 | if err != nil { | ||
| 347 | return fmt.Errorf("open access rules: %w", err) | ||
| 348 | } | ||
| 349 | defer acls.Close() | ||
| 350 | acls.AuditPath = cfg.AuditLog() | ||
| 351 | bin, err := os.Executable() | ||
| 352 | if err != nil { | ||
| 353 | bin = "vole" | ||
| 354 | } | ||
| 355 | repos := repo.New(cfg.ReposDir(), bin, acls) | ||
| 356 | m, created, err := instancerepo.Ensure(repos, name, "", "vole", cfg.InstanceName) | ||
| 357 | if err != nil { | ||
| 358 | return fmt.Errorf("instance repository %s: %w", name, err) | ||
| 359 | } | ||
| 360 | if !created { | ||
| 361 | return nil | ||
| 362 | } | ||
| 363 | ix, err := index.Open(cfg.IndexDB()) | ||
| 364 | if err != nil { | ||
| 365 | return fmt.Errorf("open index: %w", err) | ||
| 366 | } | ||
| 367 | defer ix.Close() | ||
| 368 | if err := ix.Upsert(m); err != nil { | ||
| 369 | return fmt.Errorf("index the instance repository: %w", err) | ||
| 370 | } | ||
| 371 | return nil | ||
| 372 | } | ||
| 373 | |||
| 334 | 374 | // RenameRepo moves a repository and everything keyed by its old name: the | |
| 335 | 375 | // derived index rows, the CI queue's rows and cursors, and the object store's | |
| 336 | 376 | // per-repository namespace. | |