char/sorcery
static-files based git repo viewer
git clone https://git.t4t.associates/char/sorcery
1acdf74
main
sorcery
tiny read-only git repo viewer
- point at a dir containing
user/repobare git repos - generates static sites for every repo
- serves via nginx (or other proxy supporting the
X-Accelheaders) - progressively enhances via js to provide dynamic content (commit diffs, tree-at-revision, etc)
- syntax highlighting via arborium (both serverside and clientside)
- supports "git smart HTTP" for read-only clones
pairs well with ssh git for read-write access
usage
compiles to a static executable (linux musl) on the default package in the flake:
nix build
install it as /usr/local/bin/sorceryd or whatever
nginx
production nginx config generated via @char/ngx:
deno run sorcery.ngx.ts> sorcery.conf
systemd
Example /etc/systemd/system/sorceryd.service:
[ Unit ] Description = Sorcery Git forgeAfter = network.target[ Service ] Type = simpleUser = gitGroup = gitRuntimeDirectory = sorceryCacheDirectory = sorceryConfigurationDirectory = sorceryEnvironmentFile = /etc/sorcery/envExecStart = /usr/local/bin/sorcerydRestart = on-failureRestartSec = 2UMask = 0027NoNewPrivileges = truePrivateTmp = trueProtectSystem = strictProtectHome = read-only[ Install ] WantedBy = multi-user.target
With /etc/sorcery/env:
SORCERY_REPOSITORIES =/home/git/publicSORCERY_CACHE =/var/cache/sorcerySORCERY_SOCKET =/run/sorcery/sockSORCERY_INSTANCE_NAME =my-cool-git.exampleSORCERY_CLONE_URL_BASE =https://my-cool-git.exampleSORCERY_REFRESH_TOKEN_FILE =/etc/sorcery/refresh-token
Command-line flags remain available and override the corresponding environment variables.
ssh
sorcery-ssh is an sshd ForceCommand that provides read-write git access.
it auto-creates bare repositories on first push (like sourcehut)
and also provides commands + an optional interactive tui for editing the description of a repo.
nix build .#sorcery-sshnix build .#sorcery-ssh-tui# optional
install sorcery-ssh (and sorcery-ssh-tui), ensure the git user can read /etc/sorcery/refresh-token, and add the following to sshd_config:
Match User git SetEnv SORCERY_REPOSITORIES=/home/git/public SORCERY_SOCKET=/run/sorcery/sock SORCERY_REFRESH_TOKEN_FILE=/etc/sorcery/refresh-token SORCERY_CLONE_URL_BASE=https://my-cool-git.example SORCERY_INSTANCE_NAME=my-cool-git.example SORCERY_SSH_TUI=/usr/local/bin/sorcery-ssh-tui ForceCommand /usr/local/bin/sorcery-ssh
optional: push refresh
since this is a static-files-based viewer, repositories need updating when their state changes.
if you're using sorcery-ssh, repositories will automatically refresh after a git receive-pack.
otherwise, you can use a post-receive hook like so:
#!/usr/bin/env sh repo =$( basename " $ PWD " .git) user =$( basename " $( dirname " $ PWD " ) " ) token =$( cat /etc/sorcery/refresh-token) exec curl-fsS --unix-socket /run/sorcery/sock \-H "Authorization: Bearer $ token " \-X POST"https://my-cool-git.example/-/refresh/ $ user / $ repo "
in any case, sorceryd's scanner will pick changes up eventually, so this is optional
development
cd web&& deno task check&& deno task test&& deno task buildcd ..&& cargo test
since we embed the frontend inside the executable, you must generate the frontend bundle before running a cargo build.
1# sorcery 2 3tiny read-only git repo viewer 4 5- point at a dir containing `user/repo` bare git repos 6- generates static sites for every repo 7- serves via nginx (or other proxy supporting the `X-Accel` headers) 8- progressively enhances via js to provide dynamic content (commit diffs, tree-at-revision, etc) 9- syntax highlighting via arborium (both serverside and clientside) 10- supports "git smart HTTP" for read-only clones 11 12pairs well with ssh git for read-write access 13 14## usage 15 16compiles to a static executable (linux musl) on the default package in the flake: 17 18``` sh 19nix build 20``` 21 22install it as `/usr/local/bin/sorceryd` or whatever 23 24## nginx 25 26production nginx config generated via [`@char/ngx`](https://jsr.io/@char/ngx): 27 28``` sh 29deno run sorcery.ngx.ts > sorcery.conf 30``` 31 32## systemd 33 34Example `/etc/systemd/system/sorceryd.service`: 35 36``` ini 37[ Unit ] 38Description = Sorcery Git forge 39After = network.target 40 41[ Service ] 42Type = simple 43User = git 44Group = git 45RuntimeDirectory = sorcery 46CacheDirectory = sorcery 47ConfigurationDirectory = sorcery 48EnvironmentFile = /etc/sorcery/env 49ExecStart = /usr/local/bin/sorceryd 50Restart = on-failure 51RestartSec = 2 52UMask = 0027 53NoNewPrivileges = true 54PrivateTmp = true 55ProtectSystem = strict 56ProtectHome = read-only 57 58[ Install ] 59WantedBy = multi-user.target 60``` 61 62With `/etc/sorcery/env`: 63 64``` sh 65SORCERY_REPOSITORIES=/home/git/public 66SORCERY_CACHE=/var/cache/sorcery 67SORCERY_SOCKET=/run/sorcery/sock 68SORCERY_INSTANCE_NAME=my-cool-git.example 69SORCERY_CLONE_URL_BASE=https://my-cool-git.example 70SORCERY_REFRESH_TOKEN_FILE=/etc/sorcery/refresh-token 71``` 72 73Command-line flags remain available and override the corresponding environment variables. 74 75## ssh 76 77`sorcery-ssh` is an sshd `ForceCommand` that provides read-write git access. 78it auto-creates bare repositories on first push (like sourcehut) 79and also provides commands + an optional interactive tui for editing the description of a repo. 80 81``` sh 82nix build .#sorcery-ssh 83nix build .#sorcery-ssh-tui # optional 84``` 85 86install `sorcery-ssh` (and `sorcery-ssh-tui`), ensure the `git` user can read `/etc/sorcery/refresh-token`, and add the following to `sshd_config`: 87 88``` sshconfig 89Match User git 90SetEnv SORCERY_REPOSITORIES=/home/git/public SORCERY_SOCKET=/run/sorcery/sock SORCERY_REFRESH_TOKEN_FILE=/etc/sorcery/refresh-token SORCERY_CLONE_URL_BASE=https://my-cool-git.example SORCERY_INSTANCE_NAME=my-cool-git.example SORCERY_SSH_TUI=/usr/local/bin/sorcery-ssh-tui 91ForceCommand /usr/local/bin/sorcery-ssh 92``` 93 94## optional: push refresh 95 96since this is a static-files-based viewer, repositories need updating when their state changes. 97if you're using `sorcery-ssh`, repositories will automatically refresh after a `git receive-pack`. 98otherwise, you can use a post-receive hook like so: 99 100``` sh 101#!/usr/bin/env sh 102 103repo=$(basename "$PWD" .git) 104user=$(basename "$(dirname "$PWD")") 105token=$(cat /etc/sorcery/refresh-token) 106exec curl -fsS --unix-socket /run/sorcery/sock \ 107-H "Authorization: Bearer $token" \ 108-X POST "https://my-cool-git.example/-/refresh/$user/$repo" 109``` 110 111in any case, sorceryd's scanner will pick changes up eventually, so this is optional 112 113## development 114 115``` sh 116cd web && deno task check && deno task test && deno task build 117cd .. && cargo test 118``` 119 120since we embed the frontend inside the executable, you **must** generate the frontend bundle before running a `cargo build`.