1# Soft Serve
2
3<p>
4 <img style="width: 451px" src="https://stuff.charm.sh/soft-serve/soft-serve-header.png?0" alt="A nice rendering of some melting ice cream with the words āCharm Soft Serveā next to it"><br>
5 <a href="https://github.com/charmbracelet/soft-serve/releases"><img src="https://img.shields.io/github/release/charmbracelet/soft-serve.svg" alt="Latest Release"></a>
6 <a href="https://pkg.go.dev/github.com/charmbracelet/soft-serve?tab=doc"><img src="https://godoc.org/github.com/golang/gddo?status.svg" alt="GoDoc"></a>
7 <a href="https://github.com/charmbracelet/soft-serve/actions"><img src="https://github.com/charmbracelet/soft-serve/workflows/build/badge.svg" alt="Build Status"></a>
8 <a href="https://nightly.link/charmbracelet/soft-serve/workflows/nightly/main"><img src="https://shields.io/badge/-Nightly%20Builds-orange?logo=hackthebox&logoColor=fff&style=appveyor"/></a>
9</p>
10
11A tasty, self-hostable Git server for the command line. š¦
12
13<picture>
14 <source media="(max-width: 750px)" srcset="https://github.com/charmbracelet/soft-serve/assets/42545625/c754c746-dc4c-44a6-9c39-28649264cbf2">
15 <source media="(min-width: 750px)" width="750" srcset="https://github.com/charmbracelet/soft-serve/assets/42545625/c754c746-dc4c-44a6-9c39-28649264cbf2">
16 <img src="https://github.com/charmbracelet/soft-serve/assets/42545625/c754c746-dc4c-44a6-9c39-28649264cbf2" alt="Soft Serve screencast">
17</picture>
18
19- Easy to navigate TUI available over SSH
20- Clone repos over SSH, HTTP, or Git protocol
21- Git LFS support with both HTTP and SSH backends
22- Manage repos with SSH
23- Create repos on demand with SSH or `git push`
24- Browse repos, files and commits with SSH-accessible UI
25- Print files over SSH with or without syntax highlighting and line numbers
26- Easy access control
27 - SSH authentication using public keys
28 - Allow/disallow anonymous access
29 - Add collaborators with SSH public keys
30 - Repos can be public or private
31 - User access tokens
32
33## Where can I see it?
34
35Just run `ssh git.charm.sh` for an example. You can also try some of the following commands:
36
37```bash
38# Jump directly to a repo in the TUI
39ssh git.charm.sh -t soft-serve
40
41# Print out a directory tree for a repo
42ssh git.charm.sh repo tree soft-serve
43
44# Print a specific file
45ssh git.charm.sh repo blob soft-serve cmd/soft/main.go
46
47# Print a file with syntax highlighting and line numbers
48ssh git.charm.sh repo blob soft-serve cmd/soft/main.go -c -l
49```
50
51Or you can use Soft Serve to browse local repositories using `soft browse
52[directory]` or running `soft` within a Git repository.
53
54## Installation
55
56Soft Serve is a single binary called `soft`. You can get it from a package
57manager:
58
59```bash
60# macOS or Linux
61brew install charmbracelet/tap/soft-serve
62
63# Windows (with Winget)
64winget install charmbracelet.soft-serve
65
66# Arch Linux
67pacman -S soft-serve
68
69# Nix
70nix-env -iA nixpkgs.soft-serve
71
72# Debian/Ubuntu
73sudo mkdir -p /etc/apt/keyrings
74curl -fsSL https://repo.charm.sh/apt/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/charm.gpg
75echo "deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *" | sudo tee /etc/apt/sources.list.d/charm.list
76sudo apt update && sudo apt install soft-serve
77
78# Fedora/RHEL
79echo '[charm]
80name=Charm
81baseurl=https://repo.charm.sh/yum/
82enabled=1
83gpgcheck=1
84gpgkey=https://repo.charm.sh/yum/gpg.key' | sudo tee /etc/yum.repos.d/charm.repo
85sudo yum install soft-serve
86```
87
88You can also download a binary from the [releases][releases] page. Packages are
89available in Alpine, Debian, and RPM formats. Binaries are available for Linux,
90macOS, and Windows.
91
92[releases]: https://github.com/charmbracelet/soft-serve/releases
93
94Or just install it with `go`:
95
96```bash
97go install github.com/charmbracelet/soft-serve/cmd/soft@latest
98```
99
100A [Docker image][docker] is also available.
101
102[docker]: https://github.com/charmbracelet/soft-serve/blob/main/docker.md
103
104## Setting up a server
105
106Make sure `git` is installed, then run `soft serve`. Thatās it.
107
108This will create a `data` directory that will store all the repos, ssh keys,
109and database.
110
111By default, program configuration is stored within the `data` directory. But,
112this can be overridden by setting a custom path to a config file with `SOFT_SERVE_CONFIG_LOCATION`
113that is pre-created. If a config file pointed to by `SOFT_SERVE_CONFIG_LOCATION`,
114the default location within the `data` dir is used for generating a default config.
115
116To change the default data path use `SOFT_SERVE_DATA_PATH` environment variable.
117
118```sh
119SOFT_SERVE_DATA_PATH=/var/lib/soft-serve soft serve
120```
121
122When you run Soft Serve for the first time, make sure you have the
123`SOFT_SERVE_INITIAL_ADMIN_KEYS` environment variable is set to your ssh
124authorized key. Any added key to this variable will be treated as admin with
125full privileges.
126
127Using this environment variable, Soft Serve will create a new `admin` user that
128has full privileges. You can rename and change the user settings later.
129
130Check out [Systemd][systemd] on how to run Soft Serve as a service using
131Systemd. Soft Serve packages in our Apt/Yum repositories come with Systemd
132service units.
133
134[systemd]: https://github.com/charmbracelet/soft-serve/blob/main/systemd.md
135
136### Server Configuration
137
138Once you start the server for the first time, the settings will be in
139`config.yaml` under your data directory. The default `config.yaml` is
140self-explanatory and will look like this:
141
142```yaml
143# Soft Serve Server configurations
144
145# The name of the server.
146# This is the name that will be displayed in the UI.
147name: "Soft Serve"
148
149# Log format to use. Valid values are "json", "logfmt", and "text".
150log_format: "text"
151
152# The SSH server configuration.
153ssh:
154 # The address on which the SSH server will listen.
155 listen_addr: ":23231"
156
157 # The public URL of the SSH server.
158 # This is the address that will be used to clone repositories.
159 public_url: "ssh://localhost:23231"
160
161 # The path to the SSH server's private key.
162 key_path: "ssh/soft_serve_host"
163
164 # The path to the SSH server's client private key.
165 # This key will be used to authenticate the server to make git requests to
166 # ssh remotes.
167 client_key_path: "ssh/soft_serve_client"
168
169 # The maximum number of seconds a connection can take.
170 # A value of 0 means no timeout.
171 max_timeout: 0
172
173 # The number of seconds a connection can be idle before it is closed.
174 idle_timeout: 120
175
176# The Git daemon configuration.
177git:
178 # The address on which the Git daemon will listen.
179 listen_addr: ":9418"
180
181 # The maximum number of seconds a connection can take.
182 # A value of 0 means no timeout.
183 max_timeout: 0
184
185 # The number of seconds a connection can be idle before it is closed.
186 idle_timeout: 3
187
188 # The maximum number of concurrent connections.
189 max_connections: 32
190
191# The HTTP server configuration.
192http:
193 # The address on which the HTTP server will listen.
194 listen_addr: ":23232"
195
196 # The path to the TLS private key.
197 tls_key_path: ""
198
199 # The path to the TLS certificate.
200 tls_cert_path: ""
201
202 # The public URL of the HTTP server.
203 # This is the address that will be used to clone repositories.
204 # Make sure to use https:// if you are using TLS.
205 public_url: "http://localhost:23232"
206
207 # The cross-origin request security options
208 cors:
209 # The allowed cross-origin headers
210 allowed_headers:
211 - "Accept"
212 - "Accept-Language"
213 - "Content-Language"
214 - "Content-Type"
215 - "Origin"
216 - "X-Requested-With"
217 - "User-Agent"
218 - "Authorization"
219 - "Access-Control-Request-Method"
220 - "Access-Control-Allow-Origin"
221
222 # The allowed cross-origin URLs
223 allowed_origins:
224 - "http://localhost:23232" # always allowed
225 # - "https://example.com"
226
227 # The allowed cross-origin methods
228 allowed_methods:
229 - "GET"
230 - "HEAD"
231 - "POST"
232 - "PUT"
233 - "OPTIONS"
234
235# The database configuration.
236db:
237 # The database driver to use.
238 # Valid values are "sqlite" and "postgres".
239 driver: "sqlite"
240 # The database data source name.
241 # This is driver specific and can be a file path or connection string.
242 # Make sure foreign key support is enabled when using SQLite.
243 data_source: "soft-serve.db?_pragma=busy_timeout(5000)&_pragma=foreign_keys(1)"
244
245# Git LFS configuration.
246lfs:
247 # Enable Git LFS.
248 enabled: true
249 # Enable Git SSH transfer.
250 ssh_enabled: false
251
252# Cron job configuration
253jobs:
254 mirror_pull: "@every 10m"
255
256# The stats server configuration.
257stats:
258 # The address on which the stats server will listen.
259 listen_addr: ":23233"
260# Additional admin keys.
261#initial_admin_keys:
262# - "ssh-rsa AAAAB3NzaC1yc2..."
263```
264
265You can also use environment variables, to override these settings. All server
266settings environment variables start with `SOFT_SERVE_` followed by the setting
267name all in uppercase. Here are some examples:
268
269- `SOFT_SERVE_NAME`: The name of the server that will appear in the TUI
270- `SOFT_SERVE_SSH_LISTEN_ADDR`: SSH listen address
271- `SOFT_SERVE_SSH_KEY_PATH`: SSH host key-pair path
272- `SOFT_SERVE_HTTP_LISTEN_ADDR`: HTTP listen address
273- `SOFT_SERVE_HTTP_PUBLIC_URL`: HTTP public URL used for cloning
274- `SOFT_SERVE_GIT_MAX_CONNECTIONS`: The number of simultaneous connections to git daemon
275
276#### Database Configuration
277
278Soft Serve supports both SQLite and Postgres for its database. Like all other Soft Serve settings, you can change the database _driver_ and _data source_ using either `config.yaml` or environment variables. The default config uses SQLite as the default database driver.
279
280To use Postgres as your database, first create a Soft Serve database:
281
282```sh
283psql -h<hostname> -p<port> -U<user> -c 'CREATE DATABASE soft_serve'
284```
285
286Then set the database _data source_ to point to your Postgres database. For instance, if you're running Postgres locally, using the default user `postgres` and using a database name `soft_serve`, you would have this config in your config file or environment variable:
287
288```
289db:
290 driver: "postgres"
291 data_source: "postgres://postgres@localhost:5432/soft_serve?sslmode=disable"
292```
293
294Environment variables equivalent:
295
296```sh
297SOFT_SERVE_DB_DRIVER=postgres \
298SOFT_SERVE_DB_DATA_SOURCE="postgres://postgres@localhost:5432/soft_serve?sslmode=disable" \
299soft serve
300```
301
302You can specify a database connection password in the _data source_ url. For example, `postgres://myuser:dbpass@localhost:5432/my_soft_serve_db`.
303
304#### LFS Configuration
305
306Soft Serve supports both Git LFS [HTTP](https://github.com/git-lfs/git-lfs/blob/main/docs/api/README.md) and [SSH](https://github.com/git-lfs/git-lfs/blob/main/docs/proposals/ssh_adapter.md) protocols out of the box, there is no need to do any extra set up.
307
308Use the `lfs` config section to customize your Git LFS server.
309
310> **Note**: The pure-SSH transfer is disabled by default.
311
312## Server Access
313
314Soft Serve at its core manages your server authentication and authorization. Authentication verifies the identity of a user, while authorization determines their access rights to a repository.
315
316To manage the server users, access, and repos, you can use the SSH command line interface.
317
318Try `ssh localhost -i ~/.ssh/id_ed25519 -o IdentitiesOnly=yes -p 23231 help` for more info. Make sure
319you use your key here.
320
321> **Note** The `IdentitiesOnly` option is used to prevent SSH from using any
322> other keys in your `~/.ssh` directory. This is useful when you have multiple
323> keys, and you want to use a specific key for Soft Serve.
324
325For ease of use, instead of specifying the key, port, and hostname every time
326you SSH into Soft Serve, add your own Soft Serve instance entry to your SSH
327config. For instance, to use `ssh soft` instead of typing `ssh localhost -i
328~/.ssh/id_ed25519 -o IdentitiesOnly=yes -p 23231`, we can define a `soft` entry in our SSH config
329file `~/.ssh/config`.
330
331```conf
332Host soft
333 HostName localhost
334 Port 23231
335 IdentityFile ~/.ssh/id_ed25519
336 IdentitiesOnly yes
337```
338
339Now, we can do `ssh soft` to SSH into Soft Serve. Since `git` is also aware of
340this config, you can use `soft` as the hostname for your clone commands.
341
342```sh
343git clone ssh://soft/dotfiles
344# make changes
345# add & commit
346git push origin main
347```
348
349> **Note** The `-i` and `-o` parts will be omitted in the examples below for brevity. You
350> can add your server settings to your sshconfig for quicker access.
351
352### Authentication
353
354Everything that needs authentication is done using SSH. Make sure you have
355added an entry for your Soft Serve instance in your `~/.ssh/config` file.
356
357By default, Soft Serve gives read-only permission to anonymous connections to
358any of the above protocols. This is controlled by two settings `anon-access`
359and `allow-keyless`.
360
361- `anon-access`: Defines the access level for anonymous users. Available
362 options are `no-access`, `read-only`, `read-write`, and `admin-access`.
363 Default is `read-only`.
364- `allow-keyless`: Whether to allow connections that doesn't use keys to pass.
365 Setting this to `false` would disable access to SSH keyboard-interactive,
366 HTTP, and Git protocol connections. Default is `true`.
367
368```sh
369$ ssh -p 23231 localhost settings
370Manage server settings
371
372Usage:
373 ssh -p 23231 localhost settings [command]
374
375Available Commands:
376 allow-keyless Set or get allow keyless access to repositories
377 anon-access Set or get the default access level for anonymous users
378
379Flags:
380 -h, --help help for settings
381
382Use "ssh -p 23231 localhost settings [command] --help" for more information about a command.
383```
384
385> **Note** These settings can only be changed by admins.
386
387When `allow-keyless` is disabled, connections that don't use SSH Public Key
388authentication will get denied. This means cloning repos over HTTP(s) or git://
389will get denied.
390
391Meanwhile, `anon-access` controls the access level granted to connections that
392use SSH Public Key authentication but are not registered users. The default
393setting for this is `read-only`. This will grant anonymous connections that use
394SSH Public Key authentication `read-only` access to public repos.
395
396`anon-access` is also used in combination with `allow-keyless` to determine the
397access level for HTTP(s) and git:// clone requests.
398
399#### SSH
400
401Soft Serve doesn't allow duplicate SSH public keys for users. A public key can be associated with one user only. This makes SSH authentication simple and straight forward, add your public key to your Soft Serve user to be able to access Soft Serve.
402
403#### HTTP
404
405You can generate user access tokens through the SSH command line interface. Access tokens can have an optional expiration date. Use your access token as the basic auth user to access your Soft Serve repos through HTTP.
406
407```sh
408# Create a user token
409ssh -p 23231 localhost token create 'my new token'
410ss_1234abc56789012345678901234de246d798fghi
411
412# Or with an expiry date
413ssh -p 23231 localhost token create --expires-in 1y 'my other token'
414ss_98fghi1234abc56789012345678901234de246d7
415```
416
417Now you can access to repos that require `read-write` access.
418
419```sh
420git clone http://ss_98fghi1234abc56789012345678901234de246d7@localhost:23232/my-private-repo.git my-private-repo
421# Make changes and push
422```
423
424### Authorization
425
426Soft Serve offers a simple access control. There are four access levels,
427no-access, read-only, read-write, and admin-access.
428
429`admin-access` has full control of the server and can make changes to users and repos.
430
431`read-write` access gets full control of repos.
432
433`read-only` can read public repos.
434
435`no-access` denies access to all repos.
436
437## User Management
438
439Admins can manage users and their keys using the `user` command. Once a user is
440created and has access to the server, they can manage their own keys and
441settings.
442
443To create a new user simply use `user create`:
444
445```sh
446# Create a new user
447ssh -p 23231 localhost user create beatrice
448
449# Add user keys
450ssh -p 23231 localhost user add-pubkey beatrice ssh-rsa AAAAB3Nz...
451ssh -p 23231 localhost user add-pubkey beatrice ssh-ed25519 AAAA...
452
453# Create another user with public key
454ssh -p 23231 localhost user create frankie '-k "ssh-ed25519 AAAATzN..."'
455
456# Need help?
457ssh -p 23231 localhost user help
458```
459
460Once a user is created, they get `read-only` access to public repositories.
461They can also create new repositories on the server.
462
463Users can manage their keys using the `pubkey` command:
464
465```sh
466# List user keys
467ssh -p 23231 localhost pubkey list
468
469# Add key
470ssh -p 23231 localhost pubkey add ssh-ed25519 AAAA...
471
472# Wanna change your username?
473ssh -p 23231 localhost set-username yolo
474
475# To display user info
476ssh -p 23231 localhost info
477```
478
479## Repositories
480
481You can manage repositories using the `repo` command.
482
483```sh
484# Run repo help
485$ ssh -p 23231 localhost repo help
486Manage repositories
487
488Usage:
489 ssh -p 23231 localhost repo [command]
490
491Aliases:
492 repo, repos, repository, repositories
493
494Available Commands:
495 blob Print out the contents of file at path
496 branch Manage repository branches
497 collab Manage collaborators
498 create Create a new repository
499 delete Delete a repository
500 description Set or get the description for a repository
501 hide Hide or unhide a repository
502 import Import a new repository from remote
503 info Get information about a repository
504 is-mirror Whether a repository is a mirror
505 list List repositories
506 private Set or get a repository private property
507 project-name Set or get the project name for a repository
508 rename Rename an existing repository
509 tag Manage repository tags
510 tree Print repository tree at path
511
512Flags:
513 -h, --help help for repo
514
515Use "ssh -p 23231 localhost repo [command] --help" for more information about a command.
516```
517
518To use any of the above `repo` commands, a user must be a collaborator in the repository. More on this below.
519
520### Creating Repositories
521
522To create a repository, first make sure you are a registered user. Use the
523`repo create <repo>` command to create a new repository:
524
525```sh
526# Create a new repository
527ssh -p 23231 localhost repo create icecream
528
529# Create a repo with description
530ssh -p 23231 localhost repo create icecream '-d "This is an Ice Cream description"'
531
532# ... and project name
533ssh -p 23231 localhost repo create icecream '-d "This is an Ice Cream description"' '-n "Ice Cream"'
534
535# I need my repository private!
536ssh -p 23231 localhost repo create icecream -p '-d "This is an Ice Cream description"' '-n "Ice Cream"'
537
538# Help?
539ssh -p 23231 localhost repo create -h
540```
541
542Or you can add your Soft Serve server as a remote to any existing repo, given
543you have write access, and push to remote:
544
545```
546git remote add origin ssh://localhost:23231/icecream
547```
548
549After youāve added the remote just go ahead and push. If the repo doesnāt exist
550on the server itāll be created.
551
552```
553git push origin main
554```
555
556### Nested Repositories
557
558Repositories can be nested too:
559
560```sh
561# Create a new nested repository
562ssh -p 23231 localhost repo create charmbracelet/icecream
563
564# Or ...
565git remote add charm ssh://localhost:23231/charmbracelet/icecream
566git push charm main
567```
568
569### Mirrors
570
571You can also *import* repositories from any public remote. Use the `repo import` command.
572
573```sh
574ssh -p 23231 localhost repo import soft-serve https://github.com/charmbracelet/soft-serve
575```
576
577Use `--mirror` or `-m` to mark the repository as a *pull* mirror.
578
579### Deleting Repositories
580
581You can delete repositories using the `repo delete <repo>` command.
582
583```sh
584ssh -p 23231 localhost repo delete icecream
585```
586
587### Renaming Repositories
588
589Use the `repo rename <old> <new>` command to rename existing repositories.
590
591```sh
592ssh -p 23231 localhost repo rename icecream vanilla
593```
594
595### Repository Collaborators
596
597Sometimes you want to restrict write access to certain repositories. This can
598be achieved by adding a collaborator to your repository.
599
600Use the `repo collab <command> <repo>` command to manage repo collaborators.
601
602```sh
603# Add collaborator to soft-serve
604ssh -p 23231 localhost repo collab add soft-serve frankie
605
606# Add collaborator with a specific access level
607ssh -p 23231 localhost repo collab add soft-serve beatrice read-only
608
609# Remove collaborator
610ssh -p 23231 localhost repo collab remove soft-serve beatrice
611
612# List collaborators
613ssh -p 23231 localhost repo collab list soft-serve
614```
615
616### Repository Metadata
617
618You can also change the repo's description, project name, whether it's private,
619etc using the `repo <command>` command.
620
621```sh
622# Set description for repo
623ssh -p 23231 localhost repo description icecream "This is a new description"
624
625# Hide repo from listing
626ssh -p 23231 localhost repo hidden icecream true
627
628# List repository info (branches, tags, description, etc)
629ssh -p 23231 localhost repo icecream info
630```
631
632To make a repository private, use `repo private <repo> [true|false]`. Private
633repos can only be accessed by admins and collaborators.
634
635```sh
636ssh -p 23231 localhost repo private icecream true
637```
638
639### Repository Branches & Tags
640
641Use `repo branch` and `repo tag` to list, and delete branches or tags. You can
642also use `repo branch default` to set or get the repository default branch.
643
644### Repository Tree
645
646To print a file tree for the project, just use the `repo tree` command along with
647the repo name as the SSH command to your Soft Serve server:
648
649```sh
650ssh -p 23231 localhost repo tree soft-serve
651```
652
653You can also specify the sub-path and a specific reference or branch.
654
655```sh
656ssh -p 23231 localhost repo tree soft-serve server/config
657ssh -p 23231 localhost repo tree soft-serve main server/config
658```
659
660From there, you can print individual files using the `repo blob` command:
661
662```sh
663ssh -p 23231 localhost repo blob soft-serve cmd/soft/main.go
664```
665
666You can add the `-c` flag to enable syntax coloring and `-l` to print line
667numbers:
668
669```sh
670ssh -p 23231 localhost repo blob soft-serve cmd/soft/main.go -c -l
671
672```
673
674Use `--raw` to print raw file contents. This is useful for dumping binary data.
675
676### Repository webhooks
677
678Soft Serve supports repository webhooks using the `repo webhook` command. You
679can create and manage webhooks for different repository events such as _push_,
680_collaborators_, and _branch_tag_create_ events.
681
682```
683Manage repository webhooks
684
685Usage:
686 ssh -p 23231 localhost repo webhook [command]
687
688Aliases:
689 webhook, webhooks
690
691Available Commands:
692 create Create a repository webhook
693 delete Delete a repository webhook
694 deliveries Manage webhook deliveries
695 list List repository webhooks
696 update Update a repository webhook
697
698Flags:
699 -h, --help help for webhook
700```
701
702## The Soft Serve TUI
703
704<img src="https://stuff.charm.sh/soft-serve/soft-serve-demo-commit.png" width="750" alt="TUI example showing a diff">
705
706Soft Serve TUI is mainly used to browse repos over SSH. You can also use it to
707browse local repositories with `soft browse` or running `soft` within a Git
708repository.
709
710```sh
711ssh localhost -p 23231
712```
713
714It's also possible to ālinkā to a specific repo:
715
716```sh
717ssh -p 23231 localhost -t soft-serve
718```
719
720You can copy text to your clipboard over SSH. For instance, you can press
721<kbd>c</kbd> on the highlighted repo in the menu to copy the clone command
722[^osc52].
723
724[^osc52]:
725 Copying over SSH depends on your terminal support of OSC52. Refer to
726 [go-osc52](https://github.com/aymanbagabas/go-osc52) for more information.
727
728## Hooks
729
730Soft Serve supports git server-side hooks `pre-receive`, `update`,
731`post-update`, and `post-receive`. This means you can define your own hooks to
732run on repository push events. Hooks can be defined as a per-repository hook,
733and/or global hooks that run for all repositories.
734
735You can find per-repository hooks under the repository `hooks` directory.
736
737Globs hooks can be found in your `SOFT_SERVE_DATA_PATH` directory under
738`hooks`. Defining global hooks is useful if you want to run CI/CD for example.
739
740Here's an example of sending a message after receiving a push event. Create an
741executable file `<data path>/hooks/update`:
742
743```sh
744#!/bin/sh
745#
746# An example hook script to echo information about the push
747# and send it to the client.
748
749refname="$1"
750oldrev="$2"
751newrev="$3"
752
753# Safety check
754if [ -z "$GIT_DIR" ]; then
755 echo "Don't run this script from the command line." >&2
756 echo " (if you want, you could supply GIT_DIR then run" >&2
757 echo " $0 <ref> <oldrev> <newrev>)" >&2
758 exit 1
759fi
760
761if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
762 echo "usage: $0 <ref> <oldrev> <newrev>" >&2
763 exit 1
764fi
765
766# Check types
767# if $newrev is 0000...0000, it's a commit to delete a ref.
768zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')
769if [ "$newrev" = "$zero" ]; then
770 newrev_type=delete
771else
772 newrev_type=$(git cat-file -t $newrev)
773fi
774
775echo "Hi from Soft Serve update hook!"
776echo
777echo "RefName: $refname"
778echo "Change Type: $newrev_type"
779echo "Old SHA1: $oldrev"
780echo "New SHA1: $newrev"
781
782exit 0
783```
784
785Now, you should get a message after pushing changes to any repository.
786
787## A note about RSA keys
788
789Unfortunately, due to a shortcoming in Goās `x/crypto/ssh` package, Soft Serve
790does not currently support access via new SSH RSA keys: only the old SHA-1
791ones will work.
792
793Until we sort this out youāll either need an SHA-1 RSA key or a key with
794another algorithm, e.g. Ed25519. Not sure what type of keys you have?
795You can check with the following:
796
797```sh
798$ find ~/.ssh/id_*.pub -exec ssh-keygen -l -f {} \;
799```
800
801If youāre curious about the inner workings of this problem have a look at:
802
803- https://github.com/golang/go/issues/37278
804- https://go-review.googlesource.com/c/crypto/+/220037
805- https://github.com/golang/crypto/pull/197
806
807## Contributing
808
809See [contributing][contribute].
810
811[contribute]: https://github.com/charmbracelet/soft-serve/contribute
812
813## Feedback
814
815Weād love to hear your thoughts on this project. Feel free to drop us a note!
816
817- [Twitter](https://twitter.com/charmcli)
818- [The Fediverse](https://mastodon.social/@charmcli)
819- [Discord](https://charm.sh/chat)
820
821## License
822
823[MIT](https://github.com/charmbracelet/soft-serve/raw/main/LICENSE)
824
825---
826
827Part of [Charm](https://charm.sh).
828
829<a href="https://charm.sh/"><img alt="The Charm logo" src="https://stuff.charm.sh/charm-badge.jpg" width="400"></a>
830
831Charmēē±å¼ęŗ ⢠Charm loves open source