OxygenHub
A forge for Oxygen repositories: hosting, browsing, review, issues and releases, in one Rust binary with one data directory. It works like GitHub where GitHub is right and differs where Oxygen's commutative model makes something better possible. The specification is docs/spec.md; deployment notes are in docs/deploy.md.
Status
Milestones 0.1 (browse), 0.2 (accounts and access), 0.3 (proposals and
review), 0.4 (issues and notifications), 0.5 (API, webhooks, checks) and
0.6 (web edits, releases, mirror, code search) are done: pages show
trees, files, blame, history with the dependency graph, changes with diffs,
comparisons, bookmarks, tags, conflicts, the trust policy and the push log;
accounts sign in with a password and optional TOTP, create repositories and
organisations, hold roles, mint scoped tokens for oxy, and link their
Oxygen keys so signed changes are attributed to them; proposals offer a
bookmark's changes for another with the resulting state, diff and conflicts
computed before landing, comments anchored to atoms, approvals backed by
seals, and landing from the hub or from oxy proposal land; issues with
labels, assignees, milestones, cross references and closing keywords; an
inbox with watching, subscriptions, mentions and optional email; search
over issues, proposals, repositories and accounts; a JSON API for all of
it with scoped tokens, webhooks with signed deliveries and retries, and
checks on state hashes that gate landing; editing and conflict resolution
in the browser, signed by the hub as your delegate; releases with assets
and source archives; a read-only Git mirror for Git-only tools; and code
search. The runner follows in 0.7.
Drops (oxygenhub#279) are gist-like snippets of one or more files, each
its own small Oxygen repository: made and edited in the browser, through
the API or with oh drop, every edit a signed change with history,
cloned and pushed with oxy, public or secret (listed nowhere, readable
by anyone with the address), and never listed among your repositories.
See /drops and docs/spec.md §4.5.
Install oh
Builds for Linux, macOS and Windows are on the releases page. These are early releases: the macOS and Windows builds are not signed and have had little testing.
- Debian, Ubuntu and other Linux with apt (x86_64, arm64 or riscv64):
sudo apt install ohonce the repository at https://oxygenhub.io/apt is added (see that page, or oxy's README);apt upgradethen keeps it current. Or downloadoh_VERSION_amd64.deb(or_arm64,_riscv64) from a release and runsudo 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). - Other Linux: unpack
oh-VERSION-linux-x86_64.tar.gz(or-linux-arm64) and putohon yourPATH. - macOS (Apple Silicon or Intel): unpack
oh-VERSION-macos-arm64.tar.gz(or-macos-x86_64), thenxattr -d com.apple.quarantine oh, since the build is not notarised, and put it on yourPATH. - Windows: unzip
oh-VERSION-windows-x86_64.zipand put the folder on yourPATH. SmartScreen may warn on first run, since the build is not signed.
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.
Check a download against the release's SHA256SUMS with sha256sum -c SHA256SUMS --ignore-missing.
Running
cargo build --release
target/release/oxygenhub --data /srv/oxygenhub init --base-url https://hub.example:7343 --self-signed
target/release/oxygenhub --data /srv/oxygenhub admin user create andy --admin
target/release/oxygenhub --data /srv/oxygenhub serve
Sign in, create a repository under + NEW and a token under Settings ›
Tokens, then from any checkout: oxy remote add hub https://hub.example:7343/andy/oxygen,
oxy config remote.hub.token <token> and oxy push hub. With a self-signed certificate, hand clients the CA with
OXY_CA=<path> or oxy config remote.hub.ca <path>.
Configuration lives in <data>/hub.toml (spec §17.1) and every key can be
overridden with OXYHUB_<SECTION>_<KEY>.
Layout
crates/hub the binary: config, db (sqlx + migrations), repos (registry, locks, views),
protocol (embedded oxy-server), web (pages), api (JSON), render (markdown,
highlighting, diffs, graph)
crates/hub-api the JSON API's types, shared with clients
templates/ askama templates and the stylesheet
assets/ vendored fonts, icons, the small progressive-enhancement script
migrations/ under crates/hub; applied at start
Developing
make check runs the changelog check, formatting, clippy with warnings as errors, and the tests.
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.
The tests use a real oxy-core client against a hub on a loopback port and
never touch your own Oxygen configuration.
oxygenflow and oxygen as pinned subrepos
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.
- Newer code: push oxygen, run
make pinsin oxygenflow and push it, then runmake pinshere. The next commit records the new pin. - Formatting: format only this workspace, with
cargo fmt -p oxygenhub -p hub-api.--allalso reaches the path dependencies indeps/, which have their own formatting. - Fresh clone:
oxy submodule update --inithere and indeps/oxygenflowfetches them.