| 1 |
# OxygenHub |
| 2 |
|
| 3 |
[](https://oxygenhub.io/andymccall/oxygenhub/flow) |
| 4 |
|
| 5 |
A forge for [Oxygen](../oxygen) repositories: hosting, browsing, review, |
| 6 |
issues and releases, in one Rust binary with one data directory. It works |
| 7 |
like GitHub where GitHub is right and differs where Oxygen's commutative |
| 8 |
model makes something better possible. The specification is |
| 9 |
[docs/spec.md](docs/spec.md); deployment notes are in |
| 10 |
[docs/deploy.md](docs/deploy.md). |
| 11 |
|
| 12 |
## Status |
| 13 |
|
| 14 |
Milestones 0.1 (browse), 0.2 (accounts and access), 0.3 (proposals and |
| 15 |
review), 0.4 (issues and notifications), 0.5 (API, webhooks, checks) and |
| 16 |
0.6 (web edits, releases, mirror, code search) are done: pages show |
| 17 |
trees, files, blame, history with the dependency graph, changes with diffs, |
| 18 |
comparisons, bookmarks, tags, conflicts, the trust policy and the push log; |
| 19 |
accounts sign in with a password and optional TOTP, create repositories and |
| 20 |
organisations, hold roles, mint scoped tokens for `oxy`, and link their |
| 21 |
Oxygen keys so signed changes are attributed to them; proposals offer a |
| 22 |
bookmark's changes for another with the resulting state, diff and conflicts |
| 23 |
computed before landing, comments anchored to atoms, approvals backed by |
| 24 |
seals, and landing from the hub or from `oxy proposal land`; issues with |
| 25 |
labels, assignees, milestones, cross references and closing keywords; an |
| 26 |
inbox with watching, subscriptions, mentions and optional email; search |
| 27 |
over issues, proposals, repositories and accounts; a JSON API for all of |
| 28 |
it with scoped tokens, webhooks with signed deliveries and retries, and |
| 29 |
checks on state hashes that gate landing; editing and conflict resolution |
| 30 |
in the browser, signed by the hub as your delegate; releases with assets |
| 31 |
and source archives; a read-only Git mirror for Git-only tools; and code |
| 32 |
search. The runner follows in 0.7. |
| 33 |
|
| 34 |
**Drops** (oxygenhub#279) are gist-like snippets of one or more files, each |
| 35 |
its own small Oxygen repository: made and edited in the browser, through |
| 36 |
the API or with `oh drop`, every edit a signed change with history, |
| 37 |
cloned and pushed with `oxy`, public or secret (listed nowhere, readable |
| 38 |
by anyone with the address), and never listed among your repositories. |
| 39 |
See `/drops` and docs/spec.md §4.5. |
| 40 |
|
| 41 |
## Install oh |
| 42 |
|
| 43 |
Builds for Linux, macOS, Windows and Haiku are on the [releases page](https://oxygenhub.io/andymccall/oxygenhub/releases). These are early releases: the macOS and Windows builds are not signed and have had little testing. |
| 44 |
|
| 45 |
- **Debian, Ubuntu and other Linux with apt** (x86_64, arm64 or riscv64): `sudo apt install oh` once the repository at https://oxygenhub.io/apt is added (see that page, or oxy's README); `apt upgrade` then keeps it current. Or download `oh_VERSION_amd64.deb` (or `_arm64`, `_riscv64`) from a release and run `sudo apt install ./oh_VERSION_amd64.deb`: from 0.3.1 it adds the repository by itself. It needs glibc 2.28 or later (Debian 10, Ubuntu 20.04 and newer). |
| 46 |
- **Other Linux:** unpack `oh-VERSION-linux-x86_64.tar.gz` (or `-linux-arm64`) and put `oh` on your `PATH`. |
| 47 |
- **macOS** (Apple Silicon or Intel): unpack `oh-VERSION-macos-arm64.tar.gz` (or `-macos-x86_64`), then `xattr -d com.apple.quarantine oh`, since the build is not notarised, and put it on your `PATH`. |
| 48 |
- **Windows:** unzip `oh-VERSION-windows-x86_64.zip` and run `powershell -ExecutionPolicy Bypass -File .\install.ps1` in the folder: it installs for you alone, puts `oh` on your `PATH`, and removes PowerShell's built-in alias `oh` (for `Out-Host`) in your profile, which would otherwise run instead. `ohub` is the same program under a name nothing hides. SmartScreen may warn on first run, since the build is not signed. |
| 49 |
- **Haiku** (R1/beta6, x86_64): unpack `oh-VERSION-haiku-x86_64.tar.gz` and copy `oh` to `~/config/non-packaged/bin`. It is built in a Haiku guest rather than by OxygenFlow, so it has its own `SHA256SUMS-haiku` and no build attestation. |
| 50 |
|
| 51 |
Sign in with `oh auth login --with-hub https://oxygenhub.io`; the commands are in `docs/oh.md`. `oh` works alongside `oxy`, from [Oxygen's releases](https://oxygenhub.io/andymccall/oxygen/releases). |
| 52 |
|
| 53 |
Check a download against the release's `SHA256SUMS` with `sha256sum -c SHA256SUMS --ignore-missing`. |
| 54 |
|
| 55 |
## Running |
| 56 |
|
| 57 |
``` |
| 58 |
cargo build --release |
| 59 |
target/release/oxygenhub --data /srv/oxygenhub init --base-url https://hub.example:7343 --self-signed |
| 60 |
target/release/oxygenhub --data /srv/oxygenhub admin user create andy --admin |
| 61 |
target/release/oxygenhub --data /srv/oxygenhub serve |
| 62 |
``` |
| 63 |
|
| 64 |
Sign in, create a repository under `+ NEW` and a token under Settings › |
| 65 |
Tokens, then from any checkout: `oxy remote add hub https://hub.example:7343/andy/oxygen`, |
| 66 |
`oxy config remote.hub.token <token>` and `oxy push hub`. With a self-signed certificate, hand clients the CA with |
| 67 |
`OXY_CA=<path>` or `oxy config remote.hub.ca <path>`. |
| 68 |
|
| 69 |
Configuration lives in `<data>/hub.toml` (spec §17.1) and every key can be |
| 70 |
overridden with `OXYHUB_<SECTION>_<KEY>`. |
| 71 |
|
| 72 |
## Layout |
| 73 |
|
| 74 |
``` |
| 75 |
crates/hub the binary: config, db (sqlx + migrations), repos (registry, locks, views), |
| 76 |
protocol (embedded oxy-server), web (pages), api (JSON), render (markdown, |
| 77 |
highlighting, diffs, graph) |
| 78 |
crates/hub-api the JSON API's types, shared with clients |
| 79 |
templates/ askama templates and the stylesheet |
| 80 |
assets/ vendored fonts, icons, the small progressive-enhancement script |
| 81 |
migrations/ under crates/hub; applied at start |
| 82 |
``` |
| 83 |
|
| 84 |
## Developing |
| 85 |
|
| 86 |
`make check` runs the changelog check, formatting, clippy with warnings as errors, and the tests. |
| 87 |
**Changelog:** a commit that changes code adds a line under `## Unreleased` in CHANGELOG.md (Added, Changed, Fixed or Security, with the issue number); versions change only at release. `scripts/changelog-check.sh [PATH...]` checks it for the paths a commit takes (the working copy's changes without any) and runs in the gate; `NO_CHANGELOG=1` for code changes users won't notice. |
| 88 |
|
| 89 |
The tests use a real `oxy-core` client against a hub on a loopback port and |
| 90 |
never touch your own Oxygen configuration. |
| 91 |
|
| 92 |
## oxygenflow and oxygen as pinned subrepos |
| 93 |
|
| 94 |
The hub builds against `deps/oxygenflow`, a subrepo (`oxy submodule`) pinned to an exact state, and against the oxygen that oxygenflow pins in turn, `deps/oxygenflow/deps/oxygen`. So there is one oxygen, the one oxygenflow was built and tested with, every build says which it used, and OxygenFlow can build the hub without network. |
| 95 |
|
| 96 |
- **Newer code:** push oxygen, run `make pins` in oxygenflow and push it, then run `make pins` here. The next commit records the new pin. |
| 97 |
- **Formatting:** format only this workspace, with `cargo fmt -p oxygenhub -p hub-api`. `--all` also reaches the path dependencies in `deps/`, which have their own formatting. |
| 98 |
- **Fresh clone:** `oxy submodule update --init` here and in `deps/oxygenflow` fetches them. |