Skip to content

Commit

Permalink
Merge pull request #451 from axodotdev/docs-overhaul
Browse files Browse the repository at this point in the history
chore: big docs overhaul
  • Loading branch information
Gankra authored Sep 27, 2023
2 parents d07723e + c39f60e commit e6b2b04
Show file tree
Hide file tree
Showing 46 changed files with 1,062 additions and 598 deletions.
73 changes: 62 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,69 @@
[![docs](https://docs.rs/cargo-dist/badge.svg)](https://docs.rs/cargo-dist)
[![Rust CI](https://github.com/axodotdev/cargo-dist/workflows/Rust%20CI/badge.svg?branch=main)](https://github.com/axodotdev/cargo-dist/actions/workflows/ci.yml)

`cargo build` but For Building Final Distributable Artifacts and uploading them to an archive.
*cargo-dist distributes your binaries*

The Big Idea of cargo-dist is that we want to streamline all the steps of providing prebuilt binaries
for a rust project. This includes:
The TL;DR is that with cargo-dist setup, just doing this:

1. Generating your "Cut A Release" Github CI for you
2. Picking good build flags for a "production" release
3. Making zips and installers for the resulting binaries
4. Generating a machine-readable manifest so other tools can understand the results
5. Uploading all the resulting artifacts to a Github Release™️
```sh
git commit -am "release: 0.2.0"
git tag "v0.2.0"
git push
git push --tags
```

Will make [this Github Release](https://github.com/axodotdev/axolotlsay/releases/tag/v0.2.0):

Or if you're using [oranda](https://opensource.axo.dev/oranda/), you'll get [this website](https://opensource.axo.dev/axolotlsay/).


## Plan, Build, Host, Publish, Announce

Cutting releases of your apps and distributing binaries for them has a lot of steps, and cargo-dist is quickly growing to try to cover them all!

To accomplish this, cargo-dist functionality can be broken up into two parts:

* building (**planning** the release; **building** binaries and installers)
* distributing (**hosting** artifacts; **publishing** packages; **announcing** releases)

The build functionality can be used on its own if you just want some tarballs and installers, but everything really comes together when you use the distribution functionality too.


## Building

As a build tool, cargo-dist can do the following:

* Pick good build flags for "shippable binaries"
* Make [tarballs][] and [installers][] for the resulting binaries
* Generate [machine-readable manifests][manifest] so other tools can understand the results

That's a short list because "we make [installers][]" is doing a lot of heavy lifting. Each installer could be (and sometimes is!) an entire standalone tool with its own documentation and ecosystem.


## Distributing

As a distribution tool, cargo-dist gets to flex its biggest superpower: **it generates [its own CI scripts][ci-providers]**. For instance, enabling [GitHub CI][github-ci] with `cargo dist init` will generate release.yml, which implements the full pipeline of plan, build, host, publish, announce:

* Plan
* Waits for you to push a git tag for a new version (v1.0.0, my-app-v1.0.0, my-app/1.0.0, ...)
* Selects what apps in your workspace to announce new releases for based on that tag
* Generates [a machine-readable manifest][manifest] with changelogs and build plans
* Build
* Spins up machines for each platform you support
* Builds your [binaries and tarballs][tarballs]
* Builds [installers][] for your binaries
* Publish:
* Uploads to package managers
* Host + Announce:
* Creates (or edits) a GitHub Release
* Uploads build artifacts to the Release
* Adds relevant release notes from your RELEASES/CHANGELOG

Even though cargo-dist is primarily a tool for building and packaging applications (steps 2-4), we put a fair amount of effort into Generating Your CI Scripts For You because we want to be able to run things locally and know what the CI *should* do without actually running it. It also helps avoid needless vendor lock-in -- while the extra conveniences currently only support GitHub Actions, in the future migrating from Github to Gitlab or your own personal infra will be just one invocation of cargo-dist away!
[tarballs]: https://opensource.axo.dev/cargo-dist/book/artifacts/archives.html
[installers]: https://opensource.axo.dev/cargo-dist/book/installers/index.html
[manifest]: https://opensource.axo.dev/cargo-dist/book/reference/schema.html
[github-ci]: https://opensource.axo.dev/cargo-dist/book/ci/github.html
[ci-providers]: https://opensource.axo.dev/cargo-dist/book/ci/index.html

# Read The Book!

Expand All @@ -28,8 +79,8 @@ We've got all the docs you need over at the [cargo-dist book](https://axodotdev.
* [Introduction](https://axodotdev.github.io/cargo-dist/book/introduction.html)
* [Install](https://axodotdev.github.io/cargo-dist/book/install.html)
* [Way-Too-Quickstart](https://axodotdev.github.io/cargo-dist/book/way-too-quickstart.html)
* [Guide](https://axodotdev.github.io/cargo-dist/book/guide.html)
* [Reference](https://axodotdev.github.io/cargo-dist/book/reference.html)
* [Workspaces Guide](https://axodotdev.github.io/cargo-dist/book/workspaces-guide.html)
* [Reference](https://axodotdev.github.io/cargo-dist/book/reference/index.html)

<div class="oranda-hide">

Expand Down
34 changes: 22 additions & 12 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,25 @@
- [Introduction](./introduction.md)
- [Install](./install.md)
- [Way Too Quick Start](./way-too-quickstart.md)
- [Guide](./guide.md)
- [A Simple Application](./simple-guide.md)
- [More Complex Workspaces](./workspace-guide.md)
- [Using cargo-release](./cargo-release-guide.md)
- [Customizing CI](./customizing-ci.md)
- [Reference](./reference.md)
- [Concepts](./concepts.md)
- [Config](./config.md)
- [Artifacts](./artifacts.md)
- [Installers](./installers.md)
- [CLI Manual](./cli.md)
- [dist-manifest.json](./schema.md)
- [Installers](./installers/index.md)
- [shell](./installers/shell.md)
- [powershell](./installers/powershell.md)
- [npm](./installers/npm.md)
- [homebrew](./installers/homebrew.md)
- [msi](./installers/msi.md)
- [Artifacts](./artifacts/index.md)
- [archives](./artifacts/archives.md)
- [checksums](./artifacts/checksums.md)
- [symbols](./artifacts/symbols.md)
- [CI](./ci/index.md)
- [github](./ci/github.md)
- [Workspaces](./workspaces/index.md)
- [A Simple Application](./workspaces/simple-guide.md)
- [More Complex Workspaces](./workspaces/workspace-guide.md)
- [Using cargo-release](./workspaces/cargo-release-guide.md)
- [Reference](./reference/index.md)
- [Concepts](./reference/concepts.md)
- [Artifact URLs](./reference/artifact-url.md)
- [Config](./reference/config.md)
- [CLI Manual](./reference/cli.md)
- [dist-manifest.json](./reference/schema.md)
54 changes: 0 additions & 54 deletions book/src/artifacts.md

This file was deleted.

93 changes: 93 additions & 0 deletions book/src/artifacts/archives.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Archives

Archives are the primary output of cargo-dist: a single file (zip or tarball) containing prebuilt executables/binaries for an app, along with additional static files like READMEs, LICENSEs, and CHANGELOGs. The docs previously referred to these as "executable-zips", so if you ever see that term floating around, this is what's being talked about.

When you [tell us to build an app][apps] for [a platform][config-targets] we will always make an archive for it.

[Fetching installers][fetching-installers] will fetch and unpack archives from wherever you [uploaded them][artifact-url]. [Bundling installers][bundling-installers] will use an exact copy of the binary stored in the archive, but may differ on other included files.



## Auto-Detected Files

We will always auto-detect READMEs, LICENSES, and CHANGELOGs with the following logic (described more below):

* README: [package.readme][config-package-readme], or find `README*`
* LICENSE: [package.license-file][config-package-license-file], or find `LICENSE*`/`UNLICENSE*`
* CHANGELOG: find `CHANGELOG*`/`RELEASES*`

"Find `XYZ*`" means we will look for a file whose name starts with "XYZ" in the same directory as the Cargo.toml for a package that defines the app. If no such file is found, we will also search for it in the same directory as the workspace's Cargo.toml (so packages "inherit" these files from the workspace).

It is generally assumed that a directory only contains one of each kind of file. If multiple possible matches are in the same directory we will arbitrarily pick the first one we saw, so don't rely on that.

Auto-detected files are first and foremost [auto-included into the archive](#archive-contents), however they can also be used for other things. For instance, the autodetected CHANGELOG is fed into our CHANGELOG features.



## Archive Contents

The "root" of an archive is either the actual root directory of the archive (zips); or a directory with the same name as the archive, but without the extension (tarballs). This difference is for compatibility/legacy reasons, and can be smoothed away by unpacking tarballs with tar's `--strip-components=1`.

An app's archive always includes its binaries at the root.

By default [auto-detected files](#auto-detected-files) for a package are auto-included into its archives at the root of the package. The [auto-includes][config-auto-includes] config controls this behaviour.

The [include][config-include] can be used to manually add specific files/directories to the root of the archive.



## Archive Formats

Archives can be zips or tarballs (gz, xz, or zstd).

By default we make .zip on windows and .tar.xz elsewhere, but this can be configured with [windows-archive][config-windows-archive] and [unix-archive][config-unix-archive] features.




## Build Flags

We currently [always build with `--profile=dist`][dist-profile]

By default we build with `--workspace` [to keep things consistent][workspace-hacks], but this can be configured with the [precise-builds config][config-precise-builds] (see those docs for details on when precise-builds will be force-enabled).

By default we build your packages with default features, but this can be configured with the [features][config-features], [default-features][config-default-features], and [all-features][config-all-features] configs.

When targeting windows-msvc we will unconditionally [append "-Ctarget-feature=+crt-static"][crt-static] to your RUSTFLAGS, which should just be the default for rustc but isn't for legacy reasons.

We don't really [support cross-compilation][issue-cross], but we'll faithfully attempt the compile by telling rustup to install the toolchain and passing `--target` to cargo as instructed -- it will probably just fail. On macOS cross-compiles between Intel and Apple Silicon will work. [linux-musl is slated for a future version][issue-musl].



## Code Signing

"Code Signing" is a very overloaded term, with wildly varying implementations that accomplish different goals. For instance, Linux users are currently very big on [sigstore][issue-sigstore] as a fairly turn-key code signing solution, but [neither Windows nor macOS][issue-native-sign] acknowledge its existence (and likely never will, as the benefits of sigstore completely defeat the stated purpose of code signing requirements on those platforms).

Roughly speaking, codesigning can be broken up into "Is this app made by the developer?" and "Can I trust apps made by this developer?". Tools like sigstore are focused on the former, while Windows/macOS only care about the latter. They want you to pay some money and jump through administrative hoops. They also expect you to pay completely different groups and go through completely different hoops, so each platform requires a completely different solution.


[config-package-readme]: ../reference/config.md#readme
[config-package-license-file]: ../reference/config.md#license-file
[config-windows-archive]: ../reference/config.md#windows-archive
[config-unix-archive]: ../reference/config.md#unix-archive
[config-precise-builds]: ../reference/config.md#precise-builds
[config-default-features]: ../reference/config.md#default-features
[config-all-features]: ../reference/config.md#all-features
[config-features]: ../reference/config.md#features
[config-include]: ../reference/config.md#include
[config-auto-includes]: ../reference/config.md#auto-includes
[config-targets]: ../reference/config.md#targets

[issue-musl]: https://github.com/axodotdev/cargo-dist/issues/75
[issue-cross]: https://github.com/axodotdev/cargo-dist/issues/74
[issue-sigstore]: https://github.com/axodotdev/cargo-dist/issues/120
[issue-native-sign]: https://github.com/axodotdev/cargo-dist/issues/21

[apps]: ../reference/concepts.md#defining-your-apps
[fetching-installers]: ../installers/index.md#fetching-installers
[bundling-installers]: ../installers/index.md#bundling-installers
[artifact-url]: ../reference/artifact-url.md
[dist-profile]: ../workspaces/simple-guide.md#the-dist-profile

[crt-static]: https://rust-lang.github.io/rfcs/1721-crt-static.html
[workspace-hacks]: https://docs.rs/cargo-hakari/latest/cargo_hakari/about/index.html#what-are-workspace-hack-crates
18 changes: 18 additions & 0 deletions book/src/artifacts/checksums.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Checksums

By default cargo-dist will generate a matching checksum file for each [archive][] it generates. The default checksum is sha256, so for instance `my-app-x86_64-pc-windows-msvc.zip` will also come with `my-app-x86_64-pc-windows-msvc.zip.sha256` that tools like `sha256sum` can use. This can be configured with [the checksum config][config-checksum].

[Fetching installers][fetching-installers] can also use these checksums (or ones baked into them) to validate the integrity of the files they download. With https and unsigned checksums the security benefit is minimal, but it can catch more boring problems like data corruption.

The homebrew installer actually ignores your checksum setting and always uses sha256 hashes that are baked into it, as required by homebrew itself.

Updating the other fetching installers to use these checksums is [still a work in progress][issue-checksum-backlog].



[issue-checksum-backlog]: https://github.com/axodotdev/cargo-dist/issues/439

[config-checksum]: ../reference/config.md#checksum

[archive]: ../artifacts/archives.md
[fetching-installers]: ../installers/index.md#fetching-installers
11 changes: 11 additions & 0 deletions book/src/artifacts/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Artifacts

cargo-dist exists to help you distribute your binaries, which involves generating a lot of different files which we call *Artifacts*. Archives are the baseline artifacts that contain your binaries, and installers are the fancy artifacts that make it easy to install or run the binaries.

* [Archives](./archives.md): tarballs/zips containing your binaries
* [Installers](../installers/index.md): things that help fetch/install archives
* [Checksums](./checksums.md): hashes of other artifacts
* [Symbols](./symbols.md): debuginfo/symbols/sourcemaps of your binaries



6 changes: 6 additions & 0 deletions book/src/artifacts/symbols.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Symbols

This feature is currently disabled [pending a rework][rework-symbols], but basically we want to save your debuginfo/symbols/sourcemaps in the form of pdbs, dSYMs, etc. This will automatically happen as a side-effect of building [archives][].

[rework-symbols]: https://github.com/axodotdev/cargo-dist/issues/136
[archives]: ./archives.md
1 change: 1 addition & 0 deletions book/src/ci/customizing-ci.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# CI
Loading

0 comments on commit e6b2b04

Please sign in to comment.