Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

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.

server/web/admin_instance.go +4−64

@@ -10,7 +10,7 @@ import (
10 10 "strings"
11 11 "time"
12 12
13 "github.com/rodent-software/vole/core/git"
13 "github.com/rodent-software/vole/forge/instancerepo"
14 14 )
15 15
16 16 // instanceRepoView is the Instance repository panel on the Configuration tab.
@@ -71,35 +71,10 @@ func (w *Web) CreateInstanceRepo(rw http.ResponseWriter, r *http.Request) {
71 71 w.serverError(rw, r, "the repository store is unavailable")
72 72 return
73 73 }
74 created := false
75 m, err := w.Repos.Meta(name)
74 m, created, err := instancerepo.Ensure(w.Repos, name, pr.account.Name, pr.account.Name, w.instanceName())
76 75 if err != nil {
77 m, err = w.Repos.Create(name, pr.account.Name, "Instance customization: profile README, custom CSS, favicon, and assets")
78 if err != nil {
79 w.renderAdminTab(rw, r, "configuration", err.Error(), http.StatusBadRequest)
80 return
81 }
82 created = true
83 }
84 // An existing repository with no commits is still a repository to finish, so
85 // the button seeds it rather than failing with "already exists".
86 if tip, _ := m.Git().RevParseRaw("refs/heads/" + m.DefaultBranch); tip == "" {
87 g := m.Git()
88 tree, err := git.WriteFlatTree(g, instanceRepoTemplate(w.instanceName()))
89 if err != nil {
90 w.serverError(rw, r, "starter files could not be written: "+err.Error())
91 return
92 }
93 commit, err := g.CommitTreeAs(tree, "", "Create the instance repository", pr.account.Name)
94 if err != nil {
95 w.serverError(rw, r, "starter files could not be committed: "+err.Error())
96 return
97 }
98 if err := g.UpdateRef("refs/heads/"+m.DefaultBranch, commit); err != nil {
99 w.serverError(rw, r, "the branch could not be moved: "+err.Error())
100 return
101 }
102 created = true
76 w.renderAdminTab(rw, r, "configuration", err.Error(), http.StatusBadRequest)
77 return
103 78 }
104 79 if created && w.Index != nil {
105 80 if err := w.Index.Upsert(m); err != nil {
@@ -119,38 +94,3 @@ func (w *Web) CreateInstanceRepo(rw http.ResponseWriter, r *http.Request) {
119 94 w.audit("web.admin.instance.repo", pr.account.Name, name, "created")
120 95 http.Redirect(rw, r, "/admin?tab=configuration&created=1", http.StatusSeeOther)
121 96 }
122
123 // instanceRepoTemplate is the starter tree. The root README explains the fixed
124 // paths; the profile files give the admin something to edit rather than a blank
125 // page, and the CSS names the variables worth overriding.
126 func instanceRepoTemplate(name string) map[string][]byte {
127 return map[string][]byte{
128 "README.md": []byte(`# Instance customization
129
130 This repository customizes the Vole instance. Only these paths are read; other
131 files are ignored, so this README and any notes can live here too.
132
133 profile/README.md the landing page introduction (markdown)
134 profile/private/README.md replaces it for signed-in viewers
135 profile/custom.css appended after the built-in stylesheets
136 profile/favicon.svg replaces the built-in favicon
137 assets/ served at /static/custom/assets/
138
139 Pushing to ` + "`main`" + ` updates the instance within a couple of seconds. The
140 repository is private to the instance's admins; the files above are served to
141 everyone (the private README only to signed-in viewers).
142 `),
143 "profile/README.md": []byte("# " + name + "\n\nTell people what this forge is for. This file is the landing page introduction.\n"),
144 "profile/custom.css": []byte(`/* Custom styles, loaded after the built-in stylesheets.
145 *
146 * The palette is CSS variables; override them here rather than copying rules:
147 * :root {
148 * --accent: #7fbbb3;
149 * --bg: #1e2326;
150 * }
151 *
152 * The layout is grid and flex, so most re-skins need only values, not selectors.
153 */
154 `),
155 }
156 }