Commit 9a23bcc

Nick Faro committed on
tutorial
commit 9a23bccc3e453356e9a3c760b7b3a2a2ce0b65cd parent 7ad15dd
1 changed files +115−13
ModifiedREADME.md +115−13
@@ -1,10 +1,12 @@
1 # dumbforge 1 # dumbforge
2 2
3 **the following text is not LLM generated**
4
3 Well, everyone's [been talking about GitHub alternatives](https://mitchellh.com/writing/ghostty-leaving-github) lately. I'm pretty sympathetic to that on an ideological level (and just the fundamental problem of it being down all the time), but historically the alternatives kind of suck, and I think still miss the point of Git being decentralized in the first place. [Gitea](https://gitea.com/)/[Forgejo](https://forgejo.org/) are cool, but require you to set up a server and configure it. Even though it's pretty easy, it's still annoying and requires you to pay for and babysit a VPS or whatever to run the forge program. [Codeberg](https://codeberg.org/) has been a platform of choice for freedom-heads to get away from GitHub, but they recently instituted a no-crypto and no-LLM rule. I respect what they're doing, but I'm pretty AI-pilled so that's not going to work for me. 5 Well, everyone's [been talking about GitHub alternatives](https://mitchellh.com/writing/ghostty-leaving-github) lately. I'm pretty sympathetic to that on an ideological level (and just the fundamental problem of it being down all the time), but historically the alternatives kind of suck, and I think still miss the point of Git being decentralized in the first place. [Gitea](https://gitea.com/)/[Forgejo](https://forgejo.org/) are cool, but require you to set up a server and configure it. Even though it's pretty easy, it's still annoying and requires you to pay for and babysit a VPS or whatever to run the forge program. [Codeberg](https://codeberg.org/) has been a platform of choice for freedom-heads to get away from GitHub, but they recently instituted a no-crypto and no-LLM rule. I respect what they're doing, but I'm pretty AI-pilled so that's not going to work for me.
4 6
5 It occurred to me that you don't actually need to run a forge or git daemon at all, since Git supports cloning via the so-called ["dumb" HTTP protocol](https://git-scm.com/book/en/v2/Git-Internals-Transfer-Protocols). You could theoretically just throw your git repo into an s3 bucket, and it would be clone-able, no daemon or VPS required. So that's cool, and even more decentralized; but the problem with self-hosting git like that, is that then you don't have the nice landing page, file browser, commit log, etc etc. It's small, but it makes a big difference to have a GitHubby UI for each project. [SourceHut](https://sourcehut.org/) and [Savannah](https://savannah.gnu.org/) struggle with this I think, since they're pretty alien to normies. 7 It occurred to me that you don't actually need to run a forge or git daemon at all, since Git supports cloning via the so-called ["dumb" HTTP protocol](https://git-scm.com/book/en/v2/Git-Internals-Transfer-Protocols). You could theoretically just throw your git repo into an s3 bucket, and it would be clone-able, no daemon or VPS required. So that's cool, and even more decentralized; but the problem with self-hosting git like that, is that then you don't have the nice landing page, file browser, commit log, etc etc. It's small, but it makes a big difference to have a GitHubby UI for each project. [SourceHut](https://sourcehut.org/) and [Savannah](https://savannah.gnu.org/) struggle with this I think, since they're pretty alien to normies.
6 8
7 So I slopped `dumbforge` together as a proof of concept; it's a static-site-generator like thing that functions as a git remote helper which pushes directly to an s3 bucket, and generates a GitHub-like UI. So you get some really nice advantages: 9 So I slopped `dumbforge` together as a proof of concept; it's a static-site-generator-like-thing that functions as a git remote helper which pushes directly to an s3 bucket, and generates a GitHub-like UI. So you get some really nice advantages:
8 10
9 1. It's super fast to browse, since it's just static HTML. GitLab and GitHub itself are really slow clunky beasts. 11 1. It's super fast to browse, since it's just static HTML. GitLab and GitHub itself are really slow clunky beasts.
10 2. You don't need to administer a git daemon or forge server. 12 2. You don't need to administer a git daemon or forge server.
@@ -13,6 +15,8 @@ So I slopped `dumbforge` together as a proof of concept; it's a static-site-gene
13 15
14 I'll grant that the implementation could most certainly use some improvement but this is mostly just to show off the idea. I hope it piques your curiosity. 🤔 16 I'll grant that the implementation could most certainly use some improvement but this is mostly just to show off the idea. I hope it piques your curiosity. 🤔
15 17
18 **the following text is LLM generated**
19
16 ## Install 20 ## Install
17 21
18 ```sh 22 ```sh
@@ -24,44 +28,142 @@ create packfiles instead of reimplementing its storage format.
24 28
25 ## Configure an R2 remote 29 ## Configure an R2 remote
26 30
27 Create an R2 Object Read & Write token scoped to the target bucket and save it 31 An R2 remote has two addresses:
28 in an AWS-compatible profile: 32
33 - the **S3 API endpoint**, which dumbforge uses to push with your credentials;
34 - a **public URL**, which browsers and ordinary Git use without credentials.
35
36 The S3 API endpoint is not the public URL. It normally looks like
37 `https://ACCOUNT_ID.r2.cloudflarestorage.com`. The public URL is either an
38 `r2.dev` development URL or a custom domain such as `https://git.example.com`.
39
40 ### 1. Create a bucket and make it public
41
42 In the Cloudflare dashboard, open **Storage & databases → R2**, create a bucket,
43 and open its **Settings** page. Give it either a Public Development URL or a
44 custom domain. A custom domain is preferable for anything you intend to keep;
45 the `r2.dev` URL is fine for testing.
46
47 You do not need to configure CORS. You should now have these three values:
48
49 ```text
50 Bucket: my-bucket
51 S3 endpoint: https://ACCOUNT_ID.r2.cloudflarestorage.com
52 Public URL: https://git.example.com
53 ```
54
55 ### 2. Create credentials for dumbforge
56
57 From the R2 overview, select **Manage R2 API tokens → Create API token**. Give
58 the token **Object Read & Write** access and scope it to the new bucket. When
59 Cloudflare creates it, copy the **Access Key ID** and **Secret Access Key**. The
60 secret is only shown once.
61
62 These are S3 credentials, not your normal Cloudflare API bearer token. You do
63 not need an AWS account. R2 implements the S3 protocol, and dumbforge directs
64 the S3 client to Cloudflare's endpoint.
65
66 The easiest way to save the credentials is with the AWS CLI:
29 67
30 ```sh 68 ```sh
31 aws configure --profile my-r2 69 aws configure --profile my-r2
32 ``` 70 ```
33 71
34 Use region `auto`, then add a remote from inside a local repository: 72 Answer its prompts like this:
73
74 ```text
75 AWS Access Key ID: <the R2 Access Key ID>
76 AWS Secret Access Key: <the R2 Secret Access Key>
77 Default region name: auto
78 Default output format: <press Enter>
79 ```
80
81 `aws configure` only writes a standard local credentials file. It does not
82 contact AWS or copy anything there. You can confirm that the profile can reach
83 your bucket before involving Git:
35 84
36 ```sh 85 ```sh
37 dumbforge remote add origin \ 86 aws s3api list-objects-v2 \
87 --profile my-r2 \
88 --bucket my-bucket \
89 --endpoint-url https://ACCOUNT_ID.r2.cloudflarestorage.com \
90 --max-items 1
91 ```
92
93 An empty bucket may return no objects, which is fine. An `AccessDenied` error
94 usually means the token was scoped to a different bucket or was not given
95 Object Read & Write access.
96
97 If you do not want to install the AWS CLI, export the standard
98 `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_REGION=auto` environment
99 variables instead. Omit `--profile` from the next command in that case, and
100 make sure those variables are present in every shell from which you push.
101
102 ### 3. Add the Git remote
103
104 Run this inside the local Git repository you want to publish:
105
106 ```sh
107 dumbforge remote add forge \
38 --bucket my-bucket \ 108 --bucket my-bucket \
39 --prefix projects/example.git \ 109 --prefix projects/example.git \
40 --endpoint https://ACCOUNT_ID.r2.cloudflarestorage.com \ 110 --endpoint https://ACCOUNT_ID.r2.cloudflarestorage.com \
41 --profile my-r2 \ 111 --profile my-r2 \
42 --public-url https://pub-EXAMPLE.r2.dev 112 --public-url https://git.example.com
43 ``` 113 ```
44 114
45 This configures separate URLs: 115 `forge` is merely the local name of the Git remote; choose another name if you
116 prefer. Using `forge` also leaves an existing `origin` remote alone.
117
118 The prefix is where this repository lives inside the bucket. It should normally
119 end in `.git`. You can host multiple repositories in one bucket by giving each
120 one a different prefix. Pass only the base domain to `--public-url`; dumbforge
121 appends the prefix itself.
122
123 The command configures separate fetch and push URLs:
124
125 - fetch: `https://git.example.com/projects/example.git`;
126 - push: a `dumbforge://` URL containing the bucket, endpoint, and profile.
46 127
47 - fetch: public HTTPS, usable by unmodified Git; 128 Check them with:
48 - push: `dumbforge://`, handled by `git-remote-dumbforge`.
49 129
50 Now push normally: 130 ```sh
131 git remote -v
132 ```
133
134 ### 4. Push
135
136 Push the repository's current branch. Most new repositories call it `main`:
51 137
52 ```sh 138 ```sh
53 git push --set-upstream origin main 139 git push --set-upstream forge main
54 ``` 140 ```
55 141
56 Anyone can clone without dumbforge: 142 If your branch has another name, replace `main` with the output of
143 `git branch --show-current`. The first push publishes the complete Git history
144 and builds the initial website. Later pushes upload only new Git objects and use
145 the old and new commits to rebuild changed files and affected shared pages.
146
147 Open the repository URL in a browser:
148
149 ```text
150 https://git.example.com/projects/example.git
151 ```
152
153 Anyone can clone that same URL with ordinary Git. They do not need dumbforge,
154 an R2 account, or your credentials:
57 155
58 ```sh 156 ```sh
59 git clone https://pub-EXAMPLE.r2.dev/projects/example.git 157 git clone https://git.example.com/projects/example.git
60 ``` 158 ```
61 159
62 The repository browser is served from that exact URL. Git appends 160 The repository browser is served from that exact URL. Git appends
63 `/info/refs`; browsers receive the HTML object stored at the repository prefix. 161 `/info/refs`; browsers receive the HTML object stored at the repository prefix.
64 162
163 If Git reports that `remote-dumbforge` is not a Git command, the npm global bin
164 directory is not on your `PATH`. `command -v git-remote-dumbforge` should print
165 the installed helper's path before you push.
166
65 ## Development 167 ## Development
66 168
67 ```sh 169 ```sh