1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
-
+
+
-
+
+
-
+
+
+
-
+
+
-
+
+
-
+
-
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
+
-
-
-
-
-
-
+
-
-
+
-
-
-
-
-
+
-
+
+
+
+
-
-
-
+
-
+
-
+
-
+
-
-
+
-
+
-
+
+
+
-
+
+
+
+
+
+
-
+
+
+
+
+
-
+
+
+
+
+
+
-
-
+
+
+
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
# Creating a New Repository
# Adding a Repository
How to put a new repo on fossil.craftdesign.group. Five commands, then `apply.py` does the rest: skin, Bone Hive logo, home page, public access, and the card on the landing page.
Everything needed to add a repo to fossil.craftdesign.group.
Everything happens on the server as `dmestas`. `<name>` is the URL slug, so keep it lowercase with hyphens.
## 1. Initialize the repo
## 1. Create the repository
```bash
fossil init /var/fossil/repos/<name>.fossil
fossil user new dmestas dmestas /var/fossil/repos/<name>.fossil
```
To host an existing project instead, skip `init` and copy its `.fossil` file into `/var/fossil/repos/`. Git projects are mirrored rather than copied, see [Mirrors](#mirrors) below. zit repositories cannot be read by Fossil directly: serve them with `zit serve --port 8899` and `fossil clone http://localhost:8899/ <name>.fossil` to get a Fossil file.
## 2. Set the admin password
Also set the name shown in the title bar and on the landing page, and the one-line description used as a fallback:
```bash
fossil user password dmestas <password> -R /var/fossil/repos/<name>.fossil
fossil config -R /var/fossil/repos/<name>.fossil set project-name <name>
fossil config -R /var/fossil/repos/<name>.fossil set project-description "What this repo does"
```
## 3. Create the meta sidecar
## 2. Write the meta file
Controls the icon and description shown on the landing page. Two lines — emoji icon, then description:
`/var/fossil/repos/<name>.meta` drives the landing-page card and the public access policy. One value per line:
```bash
printf '🚀\nShort description of the project' > /var/fossil/repos/<name>.meta
```
If no `.meta` file exists, the repo will appear with a `📦` icon and no description.
Optional lines 3 and 4 set the public access policy: line 3 is the Fossil capability string for `nobody` (not logged in), line 4 for `anonymous` (defaults to line 3). The default is `jh` (wiki read only). Example for a repo with a public, moderated forum:
```
| Line | Meaning | Default when missing |
|------|---------|----------------------|
| 1 | Icon: a name from the list below, or an emoji | `box` |
| 2 | Description shown on the landing page | project-description |
| 3 | Fossil capabilities for `nobody` (not logged in) | `jh` (read wiki only) |
🪨
Fossil's formats and sync protocol, reimplemented in Zig
ghoj2
ghoj23
```
| 4 | Capabilities for `anonymous` (clicked "Anonymous login") | same as line 3 |
`2` lets visitors read the forum, `3` lets anonymous users post with their posts held for moderation. The `.meta` files are versioned in the fossil-skin repo under `repos/`; edit them there and deploy, rather than only on the server.
## 4. Run apply.py
Skins the repo, sets public access policy (wiki-only), and regenerates the landing page:
```bash
python3 /var/fossil/skin/apply.py
printf 'package\nWhat this repo does\nghoj\n' > /var/fossil/repos/<name>.meta
```
## 5. Add to the login group
**Icons.** Names map to SVG files in `/var/fossil/skin/icons/` (Lucide, ISC licensed). Current set: `bone`, `box`, `diff`, `package`, `palette`, `pickaxe`, `radio-tower`, `scroll-text`, `server`. To add one, drop another `<name>.svg` from [lucide.dev/icons](https://lucide.dev/icons) into that directory and use its file name.
Allows single sign-on across all repos — log in once, authenticated everywhere:
```bash
fossil login-group join /var/fossil/repos/edgesync.fossil \
-R /var/fossil/repos/<name>.fossil
```
**Access.** Common capability strings:
Verify it joined:
- `jh` private: visitors can read the wiki, nothing else
- `ghoj` public read: files, timeline, wiki, tickets
- `ghoj2` as above plus reading the forum
- `ghoj23` on line 4 lets anonymous users post to the forum, with posts held for moderation (this is what `zit` uses)
```bash
fossil login-group -R /var/fossil/repos/<name>.fossil
```
The full list is at `/<name>/setup_ucap_list` on any repo. Lines 3 and 4 are re-applied on every `apply.py` run, so they are the source of truth for public access; changes made in the web UI get overwritten.
## 6. Create the wiki home page
## 3. Create the home page
Sets what visitors see when they land on the repo:
`apply.py` sets the repo's home page to the wiki page named `Home`, or `index` if there is no `Home`. Create one before running it (the extra "index" title is hidden by the skin, so start the page with the real heading):
```bash
fossil wiki create index -mimetype text/x-markdown \
-R /var/fossil/repos/<name>.fossil << 'WIKI'
# <name>
Description of the project.
What this repo does.
## Clone
```
fossil clone https://dmestas@fossil.craftdesign.group/<name>/ <name>.fossil
fossil clone https://fossil.craftdesign.group/<name>/ <name>.fossil
```
WIKI
```
A repo that already has a `README.md` can use that instead: `fossil wiki create index -mimetype text/x-markdown -R ... < README.md`.
## 7. Done
## 4. Join the login group
One login works across every repo on the server. Join the group through any existing member:
The repo is live at `https://fossil.craftdesign.group/<name>/` and appears on the landing page automatically.
```bash
fossil login-group join /var/fossil/repos/zit.fossil -R /var/fossil/repos/<name>.fossil
fossil login-group -R /var/fossil/repos/<name>.fossil # lists the members
```
Because of this, the new repo's `dmestas` user needs no password of its own.
---
## 5. Apply
```bash
python3 /var/fossil/skin/apply.py
```
## Full one-liner checklist
For every repo this installs the skin (CSS, header, footer), the Bone Hive logo, sets `nobody` and `anonymous` capabilities from the meta file, and sets the home page if it isn't set yet. It then regenerates the repo grid on the landing page. It is safe to run as often as you like.
The repo is now live at `https://fossil.craftdesign.group/<name>/`. Cloudflare caches nothing from Fossil itself, but browsers keep the logo for an hour.
## Copy-paste version
```bash
NAME=myrepo
PASS=changeme
DESC="What this repo does"
ICON="📦"
ICON=package # see the icon list above
CAPS=ghoj # public read; use jh for wiki-only
R=/var/fossil/repos/$NAME.fossil
fossil init /var/fossil/repos/$NAME.fossil
fossil user password dmestas $PASS -R /var/fossil/repos/$NAME.fossil
printf "$ICON\n$DESC" > /var/fossil/repos/$NAME.meta
fossil init $R
fossil user new dmestas dmestas $R
fossil config -R $R set project-name $NAME
fossil config -R $R set project-description "$DESC"
printf '%s\n%s\n%s\n' "$ICON" "$DESC" "$CAPS" > /var/fossil/repos/$NAME.meta
printf '# %s\n\n%s\n' "$NAME" "$DESC" | fossil wiki create index -mimetype text/x-markdown -R $R
fossil login-group join /var/fossil/repos/zit.fossil -R $R
python3 /var/fossil/skin/apply.py
```
fossil login-group join /var/fossil/repos/edgesync.fossil \
-R /var/fossil/repos/$NAME.fossil
## Mirrors
Repos that live on GitHub (`go-libfossil`, `edgesync`) are imported with full history by `/var/fossil/mirror/git-mirror.sh` and refreshed hourly from cron. To add one:
```bash
/var/fossil/mirror/git-mirror.sh init <name> <git-url> "<description>"
```
Then do steps 2, 4 and 5 above. Don't commit to a mirrored repo on this server; changes go to GitHub and arrive on the next sync. The log is at `/var/fossil/mirror/sync.log`.
## Where things live
| Path | What |
|------|------|
| `/var/fossil/repos/*.fossil` | the repositories |
| `/var/fossil/repos/*.meta` | icon, description, public access |
| `/var/fossil/skin/` | `apply.py`, `css.txt`, `header.txt`, `footer.txt`, `logo.png`, `icons/` |
| `/var/fossil/www/index.html` | landing page; the repo grid between the `REPO-GRID` markers is generated |
| `/var/fossil/mirror/` | git mirror script, marks files, sync log |
The skin and scripts are versioned in the [fossil-skin](/fossil-skin/) repo. Edit there, then `scp` the files to the server and run `apply.py`.
|