{"id":18950376,"url":"https://github.com/axodotdev/gazenot","last_synced_at":"2025-04-16T00:31:41.494Z","repository":{"id":207604342,"uuid":"719648979","full_name":"axodotdev/gazenot","owner":"axodotdev","description":"Gaze Not Into The Abyss, Lest You Become A Release Engineer","archived":false,"fork":false,"pushed_at":"2024-11-04T17:34:10.000Z","size":206,"stargazers_count":8,"open_issues_count":12,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-11-04T18:32:22.131Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/axodotdev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE-APACHE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-16T16:01:24.000Z","updated_at":"2024-11-04T17:33:02.000Z","dependencies_parsed_at":"2024-06-07T00:34:40.760Z","dependency_job_id":"94b09e4b-d650-493f-b1a6-6d1d0c5611e0","html_url":"https://github.com/axodotdev/gazenot","commit_stats":null,"previous_names":["axodotdev/gazenot"],"tags_count":10,"template":false,"template_full_name":"axodotdev/oss-repo-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axodotdev%2Fgazenot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axodotdev%2Fgazenot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axodotdev%2Fgazenot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axodotdev%2Fgazenot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/axodotdev","download_url":"https://codeload.github.com/axodotdev/gazenot/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223690308,"owners_count":17186592,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T13:22:44.843Z","updated_at":"2024-11-08T13:22:45.424Z","avatar_url":"https://github.com/axodotdev.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gazenot\n\n[![crates.io](https://img.shields.io/crates/v/gazenot.svg)](https://crates.io/crates/gazenot)\n[![docs](https://docs.rs/gazenot/badge.svg)](https://docs.rs/gazenot)\n[![Rust CI](https://github.com/axodotdev/gazenot/workflows/Rust/badge.svg?branch=main)](https://github.com/axodotdev/gazenot/actions/workflows/ci.yml)\n\n*Gaze Not Into The Abyss, Lest You Become A Release Engineer*\n\nGazenot is a client library for accessing Abyss, the heart of [axo Releases](https://releases.axo.dev).\n\n\n## axo Releases: An Explainer\n\nAbyss is easiest to understand as a simple package registry for prebuilt binaries.\n\n### Goals\n\nThere are several objectives to its design:\n\n* It should be easy to \"partially\" run a \"publish\" to let end-users test their release process (via cargo-dist's\n  pull-request CI)\n* It should be easy to \"rollback\" a release that failed part way through the process (e.g. because `npm publish` failed)\n* Once a release is *really* complete (\"Announced\") it should become immutable-by-default\n* Make Something Better Than GitHub Releases\n* Something Something Software-Bill-Of-Materials Features\n\n\n### Core Concepts\n\nAbyss defines the following core concepts:\n\n* A **Package** is a collection of ArtifactSets, Releases, and Announcements. It generally is 1:1 with things like A\n  Cargo Package. Typically a Package will be \"An Application\" (potentially with multiple binaries), but it can also be \"\n  A Library\" (in which case it mostly exists to host changelogs/announcements/source-tarballs). Packages belong to an\n  Owner.\n* An **ArtifactSet** is essentially a directory of files associated with a Package. It is created with no contents and a\n  permanent randomly generated Set URL. Files can be incrementally uploaded to it freely until it is \"upgraded\" to a\n  Release-Like, at which point mutation should not (by default) be allowed. If an ArtifactSet isn't \"upgraded\" then it's\n  Orphaned and eligible for garbage collection (after Many days).\n* There are 3 **Release-Likes** (although only the first is currently defined). Once created, a Release-Like \"seals\" the\n  ArtifactSet to modifications and it gets a better Artifact Download URL.\n    * A **Release** is (a layer on top of) an ArtifactSet with a Version and Tag. Creating a Release creates A Release\n      URL. Once initially created, a Release is still \"disconnected\" from the actual list of releases the package has,\n      for the purposes of requests like \"list all releases\" or \"announce all releases\". See The Pipeline for why this is\n      significant.\n    * (Theoretically) A **Release Preview** is a faux-Release that gets a Release Preview URL (as opposed to a proper\n      Release URL), allowing the Release's contents to be inspected at the user's leisure. It should in principle be\n      possible to \"upgrade\" to a real Release later, avoiding rebuilds/delays once the user is ready to Announce.\n      Unclear what's in scope for this.\n    * (Theoretically) A **PR Preview** is a more minimal Release Preview (Presumably with a PR Preview URL) for testing\n      out pull-requests (like Vercel). Conceptually this would be something like \"host a webpage with a docker image for\n      the linux build\".\n* An **Announcement** is (a layer on top of) several Releases that should be made \"truly live\" with a markdown body.\n  Creating an Announcement for a Release makes it show up in \"list all releases\" and \"what's the latest release\"\n  queries. Notably this can modify the Latest Release URL. Theoretically this could also trigger things like \"send\n  notification emails\" (A Github Releases feature) and \"post to social media\", but some of those might be \"things\n  cargo-dist does\" and not \"things Abyss does/triggers\".\n\nAnd these less-core-but-still-fundamental concepts:\n\n* An **Owner** (e.g. \"axodotdev\") is a user (or organization) of a SourceHost that owns the Package's repository (this\n  is largely managed by Sunfish, we just faithfully record the things it tells us about ownership/authentication)\n* A **SourceHost** (e.g. \"github\") is the hosting (repository) provider for the source code of a Package\n\n### The Pipeline\n\ncargo-dist defines a pipeline for releasing/announcing a package, which Abyss heavily models. The cargo-dist pipeline\nis:\n\n* **Plan**: determine how we're hosting / if hosting works\n* **Build**: build binaries/installers\n* **Host**: upload files to hosting (**THAT'S ABYSS BAYBEE!!!**)\n* **Publish**: publish to various package managers\n* **Announce**: announce the releases\n\nThe goal of separating Host, Publish, and Announce into separate steps is to allow us to get stable/pretty Release URLs\nlive in case they should be used for things like an npm package that fetches from our hosting **while still allowing the\nnpm publish to fail**. That is, by keeping the release \"disconnected\" or \"permissions: only people with this URL can\nview it\", we have the ability to still roll back the release without updating things like The Latest Release URL or The\nList Of All Releases.\n\n\u003e Note 1: currently cargo-dist always bakes in the more ugly Set URL when generating installer impls, as the design\n\u003e of Abyss currently disallows cargo-dist from knowing the Release URL until it actually invokes create-release, even\n\u003e though cargo-dist knew it would *want* to from the start. That said, this uglier mode is necessary for Release\n\u003e Preview -\u003e Release workflows, so it's good that works!\n\n\u003e Note 2: there is currently no supported functionality for doing this kind of \"Release rollback\". The user needs to\n\u003e manually intervene to throw out a Disconnected Releases, which currently would be like, emailing us. The key point is\n\u003e that *conceptually* a Disconnected Release can be totally scrapped (making its Release URL go dead), while an Announced\n\u003e Release is ideally As Forever As Possible.\n\nThe following diagram depicts how Abyss's concepts map to this pipeline (and which endpoints cargo-dist invokes during\neach one).\n\n```mermaid\nflowchart LR\n    subgraph plan\n      create-artifact-set\n      check-auth[\"check-auth\\n(technically feeds to Build too\\nwith fake URLs, but not host)\"]\n    end\n    subgraph build[\"build (not modeled by Abyss)\"]\n        fake2([build apps\\nbuild installers\\n...])\n    end\n    subgraph host\n      upload-file[\"upload-file\\n(many times)\"]\n      create-release\n      create-release-preview\n      create-pr-preview\n    end\n    subgraph publish[\"publish (not modeled by Abyss)\"]\n        fake1([publish to crates.io\\npublish to npm\\npublish to homebrew\\n...])\n    end    \n    subgraph announce\n    F[create-announcement]\n    end\n    create-artifact-set --\u003e build\n    build --\u003e upload-file\n    upload-file --\u003e create-release\n    upload-file --\u003e create-release-preview\n    upload-file --\u003e create-pr-preview\n    create-release-preview --\u003e create-release\n    create-release --\u003e publish\n    publish --\u003e announce\n```\n\n(Arguably create-release is a \"the first publish step\" but cargo-dist currently lumps it into \"host\" and that\nincreasingly feels correct/simpler *shrug*...)\n\n### Artifact Download URLs\n\nOne of the core side-effects of Abyss is Making URLs You Can Download Artifacts From. Because it breaks the release\nprocess into multiple stages, there are many Kinds of Artifact Download URL. These all point to CDN hosting, and\n*not* Abyss.\n\n* A **Set Url** (`https://myuser.artifacts.axodotdev.host/myapp/ax_UJl_tKCujZwxKL1n_K7TM`) is a permanent randomly\n  generated URL for downloading files from an ArtifactSet. It can be embedded in things like the bodies of curl-sh\n  installers made by cargo-dist, but ideally it **should never** be presented to end-users in things like curl-sh\n  *expressions* which show up on oranda websites, install widgets, or announcement posts.\n* A **Release URL** (`https://myuser.artifacts.axodotdev.host/myapp/v1.0.0/`) is a permanent stable-format URL for\n  downloading files from a Release('s ArtifactSet). This is typically what should be presented in curl-sh *expressions*.\n  This URL may go dead if a Release is never Announced.\n* A **Latest (Release) URL** (`https://myuser.artifacts.axodotdev.host/myapp/latest/`) is a mutable-destination\n  stable-format URL for downloading \"whatever the latest Release('s ArtifactSet) is\". This URL is appropriate for\n  linking in random docs which you don't want to update every time there's a release.\n* (Theoretically) A **Release Preview URL** ...\n* (Theoretically) A **PR Preview URL** ...\n\n\n\n\n## License\n\nLicensed under either of\n\n* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or [apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0))\n* MIT license ([LICENSE-MIT](LICENSE-MIT) or [opensource.org/licenses/MIT](https://opensource.org/licenses/MIT))\n\nat your option.\n\n## Contributions\n\nUnless you explicitly state otherwise, any contribution intentionally\nsubmitted for inclusion in the work by you, as defined in the Apache-2.0\nlicense, shall be dual licensed as above, without any additional terms or\nconditions.\n\nIf you are interested in contributing, please read our [CONTRIBUTING notes] and our [Code of Conduct].\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faxodotdev%2Fgazenot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faxodotdev%2Fgazenot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faxodotdev%2Fgazenot/lists"}