Releases: axodotdev/cargo-dist
Version 0.0.3-prerelease05 (under development)
Release Notes
USE AT YOUR OWN RISK, SUPER ALPHA
A major overhaul has been done to the design to rationalize some improperly defined features/behaviours, when you update to this version you will need to rerun cargo dist init
(and need to generate-ci).
Configuration (Cargo.toml)
You can now persistently configure cargo-dist with [workspace.metadata.dist]
in your root Cargo.toml, with the ability to override some settings per-package with [package.metadata.dist]
.
The following settings can only be set in [workspace]
:
- cargo-dist-version: (Cargo SemVer format) specifies the desired version of cargo-dist for building the project. Currently only used when generating CI scripts. When you run
cargo dist init
the version you're using will be set here. If omitted, every time you runcargo dist generate-ci
it will just bake in the version of cargo dist you are currently locally running. - rust-toolchain-version: (rustup toolchain format) species the desired version of rust/cargo for building the project. Currently only used when generating CI scripts. When you run
cargo dist init
we currently just select a hardcoded stable release (1.67.1). If omitted we will just select the "stable" toolchain (which will drift over time). - ci: a list of CI backends to support (currently only
["github"]
will work). This is used bycargo dist generate-ci
so you no longer need to pass the flag every time. It's also used to detect the format to use for download URLs (for things like installer scripts).
The following settings can be set on either [workspace]
or [package]
, with the latter overriding the former:
- dist: (bool, defaults to "undefined") whether this package's binaries should be visible to cargo-dist for the purposes of Releases. If undefined, we will defer to cargo's own publish=false config. Packages without binaries are always invisible to cargo-dist.
- installers: (list of installer kinds) the default set of installers to generate for releases (currently only "shell" and "powershell" are defined)
- targets: (list of rust-style target-triples) the default set of targets to use for releases (sort of, see the section on CLI configuration)
- include: (list of paths relative to that Cargo.toml's dir) extra files to include in executable-zips (does not currently support directories or wildcards, individual files only)
- auto-includes: (bool, defaults true) whether dist should add README/LICENSE/etc files to your executable-zips when it finds them.
Configuration (Artifact CLI flags)
Previously cargo-dist had some vague notions of what it was supposed to do when you invoked it, because there were platform-specific artifacts like executable-zips but also more platform-agnostic ones like installer scripts. This result in flags like --no-builds
with messy semantics and hacks to filter out artifacts we "don't want right now" in the CI scripts (--no-builds
was is removed in this release, it was busted).
Now cargo-dist can produce well-defined subsets of the all possible artifacts with the --artifacts
flag:
--artifacts = "local" | "global" | "all" | "host"
Artifacts can be broken up into two major classes:
- local: made for each target system (executable-zips, symbols, MSIs...)
- global: made once (curl-sh installers, npm package, metadata...)
("all" selects both of these at once)
Having this distinction lets us run cargo-dist independently on multiple machines without collisions between the outputs by spinning up machines that run something like:
- linux-runner1 (get full manifest): cargo-dist manifest --artifacts=all --output-format=json
- linux-runner2 (get global artifacts): cargo-dist --artifacts=global
- linux-runner3 (get linux artifacts): cargo-dist --artifacts=local --target=x86_64-unknown-linux-gnu
- windows-runner (get windows artifacts): cargo-dist --artifacts=local --target=x86_64-pc-windows-msvc
If let unspecified, we will pick a fuzzier "host" mode that builds "as much as possible" for the local system. This mode is appropriate for local testing/debugging/demoing. If no --target flags are passed on the CLI then "host" mode will try to intelligently guess which targets to build for, which may include building targets that aren't defined in your metadata.dist config (since that config may exclude the current machine!).
The specifics of "host" mode are intentionally unspecified to enable us to provider better out-of-the-box UX for local usage. In CI environments you should always specify one of the other tree options!
Note that the introduction of persistent Cargo.toml configuration is crucial to this semantic redesign, as it allows each invocation to be aware of the "full" set of artifacts across all platforms, and then filter down to it.
If you pass --installer
, --ci
, or --target
this will replace the Cargo.toml value for all packages for that invocation. This is most useful for --target
in conjuction with --artifacts=local
as it lets us precisely select which platform-specific artifacts to build on the current machine (all 3 of these flags can be passed repeatedly).
WARING! If you specify --artifacts and --target, the selected targets can only be a subset of the ones defined in your Cargo.toml. This ensures cargo dist --artifacts=global
has behaviour consistent with cargo dist --artifacts=local --target=...
, as global artifacts need to be aware of all targets at once. "host" mode bypasses this restriction so that runs of cargo dist on developer machines can do something useful even if the Cargo.toml doesn't know about the host platform.
Configuration (Announcement/Release Selection)
There is also now a --tag
flag for specifying the git tag to use for announcing a new release. This tag must have a specific format detailed below. The tag serves two purposes:
- It specifies the subset of the workspace that we want to Announce/Release
- When using CI, it becomes the unique ID for a Github Release, which is necessary for everything to correctly compute download URLs
cargo dist build
and cargo dist manifest
now both require that you either specify a --tag that "makes sense", or that your workspace is simple enough for a tag to be computed for you. In CI, each git tag you push will create an independent run of cargo-dist's CI to make a Github Release for that tag, and each invocation of cargo-dist will have that tag passed to it, ensuring they all agree on the above details.
There are two kinds of tag formats that are accepted:
- Unified Announcement:
v{VERSION}
selects all packages with the given version (v1.0.0, v0.1.0-prerelease, etc.) - Singular Announcement:
{PACKAGE-NAME}-v{VERSION}
selects only the given package (error if the version doesn't match)
Note that other criteria may prevent a package from being selected: it has no binaries, it has dist=false, it has publish=false, etc. If you do not specify a --tag, cargo-dist will check if all still-selectable packages share a version, and if they do it will make a Unified Announcement for them (erroring otherwise).
These two modes support the following workflow:
- Releasing a workspace with only one binary-having package (either mode works but Unified is Cleaner)
- Releasing a workspace where all binary-having packages are versioned in lockstep (Unified)
- Releasing an individual package in a workspace with its own independent versioning (Singular)
- Releasing several packages in a workspace at once, but all independently (Push multiple Singular tags at once)
Basically the one thing we can't deal with is you saying "I would like a single coherent Announcement (Github Release) for packageA 0.1.0 and packageB 0.2.0", because nothing really ties them together. If you disagree, please let us know how you think it can/should work!
Although you could use extremely careful versioning in conjuction with Unified Announcements to release a weird subset of the packages in your workspace, you really shouldn't because the Github Releases will be incoherent (v0.1.0 has these random packages, v0.2.0 has these other random packages... huh?), and you're liable to create painful tag collisions.
WARNING! cargo-release largely already generates tags that express these exact semantics, except for one annoying corner case (that I've found so far): if you have a non-virtual workspace (the root Cargo.toml is an actual package with child packages), it will always try to tag releases of the root package with a Unified Tag, even when trying using --workspace
. This will not play well with cargo-dist. Initial testing suggests virtual workspaces behave much better.
WARNING! cargo-dist currently errors out if you provide a Singular tag for a library-only package (or a Unified Tag that selects only similarly unselectable packages). This is bad UX, but we need to figure out a story for what to do in that situation. (We could just make a Github Release with no artifacts, maybe still grab your Release Notes..?)
Release Notes
Release notes are now temporarily simplified for reliability:
-
For the purposes of a top level Announcement (Github Release), notes are now no longer associated with the individual apps being published, meaning there's only one set of notes generated.
-
If you have a RELEASES* or CHANGELOG* file in the root of your workspace, we will assume these are the release notes for any Unified Announcement (see the previous section) and try to include the relevant section at the top of the Github Release. This is done with the parse_changelog library. If parsing/lookup fails we continue on silently.
-
If the above process succeeds, the heading of the section we found will become the new title of the Github Release. For example, if we find
1.2.0
matches# Version 1.2.0 (2023-01-25)
, th...
Version 0.0.3-prerelease04 (not yet released!)
Release Notes
USE AT YOUR OWN RISK, SUPER ALPHA
A major overhaul has been done to the design to rationalize some improperly defined features/behaviours, when you update to this version you will need to rerun cargo dist init
(and need to generate-ci).
Configuration (Cargo.toml)
You can now persistently configure cargo-dist with [workspace.metadata.dist]
in your root Cargo.toml, with the ability to override some settings per-package with [package.metadata.dist]
.
The following settings can only be set in [workspace]
:
- cargo-dist-version: (Cargo SemVer format) specifies the desired version of cargo-dist for building the project. Currently only used when generating CI scripts. When you run
cargo dist init
the version you're using will be set here. If omitted, every time you runcargo dist generate-ci
it will just bake in the version of cargo dist you are currently locally running. - rust-toolchain-version: (rustup toolchain format) species the desired version of rust/cargo for building the project. Currently only used when generating CI scripts. When you run
cargo dist init
we currently just select a hardcoded stable release (1.67.1). If omitted we will just select the "stable" toolchain (which will drift over time). - ci: a list of CI backends to support (currently only
["github"]
will work). This is used bycargo dist generate-ci
so you no longer need to pass the flag every time. It's also used to detect the format to use for download URLs (for things like installer scripts).
The following settings can be set on either [workspace]
or [package]
, with the latter overriding the former:
- dist: (bool, defaults to "undefined") whether this package's binaries should be visible to cargo-dist for the purposes of Releases. If undefined, we will defer to cargo's own publish=false config. Packages without binaries are always invisible to cargo-dist.
- installers: (list of installer kinds) the default set of installers to generate for releases (currently only "shell" and "powershell" are defined)
- targets: (list of rust-style target-triples) the default set of targets to use for releases (sort of, see the section on CLI configuration)
- include: (list of paths relative to that Cargo.toml's dir) extra files to include in executable-zips (does not currently support directories or wildcards, individual files only)
- auto-includes: (bool, defaults true) whether dist should add README/LICENSE/etc files to your executable-zips when it finds them.
Configuration (Artifact CLI flags)
Previously cargo-dist had some vague notions of what it was supposed to do when you invoked it, because there were platform-specific artifacts like executable-zips but also more platform-agnostic ones like installer scripts. This result in flags like --no-builds
with messy semantics and hacks to filter out artifacts we "don't want right now" in the CI scripts (--no-builds
was is removed in this release, it was busted).
Now cargo-dist can produce well-defined subsets of the all possible artifacts with the --artifacts
flag:
--artifacts = "local" | "global" | "all" | "host"
Artifacts can be broken up into two major classes:
- local: made for each target system (executable-zips, symbols, MSIs...)
- global: made once (curl-sh installers, npm package, metadata...)
("all" selects both of these at once)
Having this distinction lets us run cargo-dist independently on multiple machines without collisions between the outputs by spinning up machines that run something like:
- linux-runner1 (get full manifest): cargo-dist manifest --artifacts=all --output-format=json
- linux-runner2 (get global artifacts): cargo-dist --artifacts=global
- linux-runner3 (get linux artifacts): cargo-dist --artifacts=local --target=x86_64-unknown-linux-gnu
- windows-runner (get windows artifacts): cargo-dist --artifacts=local --target=x86_64-pc-windows-msvc
If let unspecified, we will pick a fuzzier "host" mode that builds "as much as possible" for the local system. This mode is appropriate for local testing/debugging/demoing. If no --target flags are passed on the CLI then "host" mode will try to intelligently guess which targets to build for, which may include building targets that aren't defined in your metadata.dist config (since that config may exclude the current machine!).
The specifics of "host" mode are intentionally unspecified to enable us to provider better out-of-the-box UX for local usage. In CI environments you should always specify one of the other tree options!
Note that the introduction of persistent Cargo.toml configuration is crucial to this semantic redesign, as it allows each invocation to be aware of the "full" set of artifacts across all platforms, and then filter down to it.
If you pass --installer
, --ci
, or --target
this will replace the Cargo.toml value for all packages for that invocation. This is most useful for --target
in conjuction with --artifacts=local
as it lets us precisely select which platform-specific artifacts to build on the current machine (all 3 of these flags can be passed repeatedly).
WARING! If you specify --artifacts and --target, the selected targets can only be a subset of the ones defined in your Cargo.toml. This ensures cargo dist --artifacts=global
has behaviour consistent with cargo dist --artifacts=local --target=...
, as global artifacts need to be aware of all targets at once. "host" mode bypasses this restriction so that runs of cargo dist on developer machines can do something useful even if the Cargo.toml doesn't know about the host platform.
Configuration (Announcement/Release Selection)
There is also now a --tag
flag for specifying the git tag to use for announcing a new release. This tag must have a specific format detailed below. The tag serves two purposes:
- It specifies the subset of the workspace that we want to Announce/Release
- When using CI, it becomes the unique ID for a Github Release, which is necessary for everything to correctly compute download URLs
cargo dist build
and cargo dist manifest
now both require that you either specify a --tag that "makes sense", or that your workspace is simple enough for a tag to be computed for you. In CI, each git tag you push will create an independent run of cargo-dist's CI to make a Github Release for that tag, and each invocation of cargo-dist will have that tag passed to it, ensuring they all agree on the above details.
There are two kinds of tag formats that are accepted:
- Unified Announcement:
v{VERSION}
selects all packages with the given version (v1.0.0, v0.1.0-prerelease, etc.) - Singular Announcement:
{PACKAGE-NAME}-v{VERSION}
selects only the given package (error if the version doesn't match)
Note that other criteria may prevent a package from being selected: it has no binaries, it has dist=false, it has publish=false, etc. If you do not specify a --tag, cargo-dist will check if all still-selectable packages share a version, and if they do it will make a Unified Announcement for them (erroring otherwise).
These two modes support the following workflow:
- Releasing a workspace with only one binary-having package (either mode works but Unified is Cleaner)
- Releasing a workspace where all binary-having packages are versioned in lockstep (Unified)
- Releasing an individual package in a workspace with its own independent versioning (Singular)
- Releasing several packages in a workspace at once, but all independently (Push multiple Singular tags at once)
Basically the one thing we can't deal with is you saying "I would like a single coherent Announcement (Github Release) for packageA 0.1.0 and packageB 0.2.0", because nothing really ties them together. If you disagree, please let us know how you think it can/should work!
Although you could use extremely careful versioning in conjuction with Unified Announcements to release a weird subset of the packages in your workspace, you really shouldn't because the Github Releases will be incoherent (v0.1.0 has these random packages, v0.2.0 has these other random packages... huh?), and you're liable to create painful tag collisions.
WARNING! cargo-release largely already generates tags that express these exact semantics, except for one annoying corner case (that I've found so far): if you have a non-virtual workspace (the root Cargo.toml is an actual package with child packages), it will always try to tag releases of the root package with a Unified Tag, even when trying using --workspace
. This will not play well with cargo-dist. Initial testing suggests virtual workspaces behave much better.
WARNING! cargo-dist currently errors out if you provide a Singular tag for a library-only package (or a Unified Tag that selects only similarly unselectable packages). This is bad UX, but we need to figure out a story for what to do in that situation. (We could just make a Github Release with no artifacts, maybe still grab your Release Notes..?)
Release Notes
Release notes are now temporarily simplified for reliability:
-
For the purposes of a top level Announcement (Github Release), notes are now no longer associated with the individual apps being published, meaning there's only one set of notes generated.
-
If you have a RELEASES* or CHANGELOG* file in the root of your workspace, we will assume these are the release notes for any Unified Announcement (see the previous section) and try to include the relevant section at the top of the Github Release. This is done with the parse_changelog library. If parsing/lookup fails we continue on silently.
-
If the above process succeeds, the heading of the section we found will become the new title of the Github Release. For example, if we find
1.2.0
matches# Version 1.2.0 (2023-01-25)
, th...
Version 0.0.3-prerelease03 (still being tested!!!)
Install cargo-dist 0.0.3-prerelease03
Install prebuilt binaries via shell script
# WARNING: this installer is experimental
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.3-prerelease03/cargo-dist-v0.0.3-prerelease03-installer.sh | sh
Install prebuilt binaries via powershell script
# WARNING: this installer is experimental
irm https://github.com/axodotdev/cargo-dist/releases/download/v0.0.3-prerelease03/cargo-dist-v0.0.3-prerelease03-installer.ps1 | iex
Download cargo-dist 0.0.3-prerelease03
target | kind | download |
---|---|---|
x86_64-apple-darwin | tarball | cargo-dist-v0.0.3-prerelease03-x86_64-apple-darwin.tar.xz |
x86_64-pc-windows-msvc | tarball | cargo-dist-v0.0.3-prerelease03-x86_64-pc-windows-msvc.zip |
x86_64-unknown-linux-gnu | tarball | cargo-dist-v0.0.3-prerelease03-x86_64-unknown-linux-gnu.tar.xz |
x86_64-pc-windows-msvc | symbols | cargo-dist-v0.0.3-prerelease03-x86_64-pc-windows-msvc.pdb |
Release Notes
USE AT YOUR OWN RISK, SUPER ALPHA
A major overhaul has been done to the design to rationalize some improperly defined features/behaviours, when you update to this version you will need to rerun cargo dist init
(and need to generate-ci).
Configuration (Cargo.toml)
You can now persistently configure cargo-dist with [workspace.metadata.dist]
in your root Cargo.toml, with the ability to override some settings per-package with [package.metadata.dist]
.
The following settings can only be set in [workspace]
:
- cargo-dist-version: (Cargo SemVer format) specifies the desired version of cargo-dist for building the project. Currently only used when generating CI scripts. When you run
cargo dist init
the version you're using will be set here. If omitted, every time you runcargo dist generate-ci
it will just bake in the version of cargo dist you are currently locally running. - rust-toolchain-version: (rustup toolchain format) species the desired version of rust/cargo for building the project. Currently only used when generating CI scripts. When you run
cargo dist init
we currently just select a hardcoded stable release (1.67.1). If omitted we will just select the "stable" toolchain (which will drift over time). - ci: a list of CI backends to support (currently only
["github"]
will work). This is used bycargo dist generate-ci
so you no longer need to pass the flag every time. It's also used to detect the format to use for download URLs (for things like installer scripts).
The following settings can be set on either [workspace]
or [package]
, with the latter overriding the former:
- dist: (bool, defaults to "undefined") whether this package's binaries should be visible to cargo-dist for the purposes of Releases. If undefined, we will defer to cargo's own publish=false config. Packages without binaries are always invisible to cargo-dist.
- installers: (list of installer kinds) the default set of installers to generate for releases (currently only "github-shell" and "github-powershell" are defined)
- targets: (list of rust-style target-triples) the default set of targets to use for releases (sort of, see the section on CLI configuration)
- include: (list of paths relative to that Cargo.toml's dir) extra files to include in executable-zips (does not currently support directories or wildcards, individual files only)
- auto-includes: (bool, defaults true) whether dist should add README/LICENSE/etc files to your executable-zips when it finds them.
Configuration (Artifact CLI flags)
Previously cargo-dist had some vague notions of what it was supposed to do when you invoked it, because there were platform-specific artifacts like executable-zips but also more platform-agnostic ones like installer scripts. This result in flags like --no-builds
with messy semantics and hacks to filter out artifacts we "don't want right now" in the CI scripts (--no-builds
was is removed in this release, it was busted).
Now cargo-dist can produce well-defined subsets of the all possible artifacts with the --artifacts
flag:
--artifacts = "local" | "global" | "all" | "host"
Artifacts can be broken up into two major classes:
- local: made for each target system (executable-zips, symbols, MSIs...)
- global: made once (curl-sh installers, npm package, metadata...)
("all" selects both of these at once)
Having this distinction lets us run cargo-dist independently on multiple machines without collisions between the outputs by spinning up machines that run something like:
- linux-runner1 (get full manifest): cargo-dist manifest --artifacts=all --output-format=json
- linux-runner2 (get global artifacts): cargo-dist --artifacts=global
- linux-runner3 (get linux artifacts): cargo-dist --artifacts=local --target=x86_64-unknown-linux-gnu
- windows-runner (get windows artifacts): cargo-dist --artifacts=local --target=x86_64-pc-windows-msvc
If let unspecified, we will pick a fuzzier "host" mode that builds "as much as possible" for the local system. This mode is appropriate for local testing/debugging/demoing. If no --target flags are passed on the CLI then "host" mode will try to intelligently guess which targets to build for, which may include building targets that aren't defined in your metadata.dist config (since that config may exclude the current machine!).
The specifics of "host" mode are intentionally unspecified to enable us to provider better out-of-the-box UX for local usage. In CI environments you should always specify one of the other tree options!
Note that the introduction of persistent Cargo.toml configuration is crucial to this semantic redesign, as it allows each invocation to be aware of the "full" set of artifacts across all platforms, and then filter down to it.
If you pass --installer
, --ci
, or --target
this will replace the Cargo.toml value for all packages for that invocation. This is most useful for --target
in conjuction with --artifacts=local
as it lets us precisely select which platform-specific artifacts to build on the current machine (all 3 of these flags can be passed repeatedly).
WARING! If you specify --artifacts and --target, the selected targets can only be a subset of the ones defined in your Cargo.toml. This ensures cargo dist --artifacts=global
has behaviour consistent with cargo dist --artifacts=local --target=...
, as global artifacts need to be aware of all targets at once. "host" mode bypasses this restriction so that runs of cargo dist on developer machines can do something useful even if the Cargo.toml doesn't know about the host platform.
Configuration (Announcement/Release Selection)
There is also now a --tag
flag for specifying the git tag to use for announcing a new release. This tag must have a specific format detailed below. The tag serves two purposes:
- It specifies the subset of the workspace that we want to Announce/Release
- When using CI, it becomes the unique ID for a Github Release, which is necessary for everything to correctly compute download URLs
cargo dist build
and cargo dist manifest
now both require that you either specify a --tag that "makes sense", or that your workspace is simple enough for a tag to be computed for you. In CI, each git tag you push will create an independent run of cargo-dist's CI to make a Github Release for that tag, and each invocation of cargo-dist will have that tag passed to it, ensuring they all agree on the above details.
There are two kinds of tag formats that are accepted:
- Unified Announcement:
v{VERSION}
selects all packages with the given version (v1.0.0, v0.1.0-prerelease, etc.) - Singular Announcement:
{PACKAGE-NAME}-v{VERSION}
selects only the given package (error if the version doesn't match)
Note that other criteria may prevent a package from being selected: it has no binaries, it has dist=false, it has publish=false, etc. If you do not specify a --tag, cargo-dist will check if all still-selectable packages share a version, and if they do it will make a Unified Announcement for them (erroring otherwise).
These two modes support the following workflow:
- Releasing a workspace with only one binary-having package (either mode works but Unified is Cleaner)
- Releasing a workspace where all binary-having packages are versioned in lockstep (Unified)
- Releasing an individual package in a workspace with its own independent versioning (Singular)
- Releasing several packages in a workspace at once, but all independently (Push multiple Singular tags at once)
Basically the one thing we can't deal with is you saying "I would like a single coherent Announcement (Github Release) for packageA 0.1.0 and packageB 0.2.0", because nothing really ties them together. If you disagree, please let us know how you think it can/should work!
Although you could use extremely careful versioning in conjuction with Unified Announcements to release a weird subset of the packages in your workspace, you really shouldn't because the Github Releases will be incoherent (v0.1.0 has these random packages, v0.2.0 has these other random packages... huh?), and you're liable to create painful tag collisions.
WARNING! cargo-release largely already generates tags that express these exact semantics, except for one annoying corner case (that I've found so far): if ...
Version 0.0.3-prerelease02 (still being tested!!!)
Install cargo-dist 0.0.3-prerelease02
Install prebuilt binaries via shell script
# WARNING: this installer is experimental
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.3-prerelease02/cargo-dist-v0.0.3-prerelease02-installer.sh | sh
Install prebuilt binaries via powershell script
# WARNING: this installer is experimental
irm https://github.com/axodotdev/cargo-dist/releases/download/v0.0.3-prerelease02/cargo-dist-v0.0.3-prerelease02-installer.ps1 | iex
Download cargo-dist 0.0.3-prerelease02
target | kind | download |
---|---|---|
x86_64-apple-darwin | tarball | cargo-dist-v0.0.3-prerelease02-x86_64-apple-darwin.tar.xz |
x86_64-pc-windows-msvc | tarball | cargo-dist-v0.0.3-prerelease02-x86_64-pc-windows-msvc.zip |
x86_64-unknown-linux-gnu | tarball | cargo-dist-v0.0.3-prerelease02-x86_64-unknown-linux-gnu.tar.xz |
x86_64-pc-windows-msvc | symbols | cargo-dist-v0.0.3-prerelease02-x86_64-pc-windows-msvc.pdb |
Release Notes
USE AT YOUR OWN RISK, SUPER ALPHA
A major overhaul has been done to the design to rationalize some improperly defined features/behaviours, when you update to this version you will need to rerun cargo dist init
(and need to generate-ci).
Configuration (Cargo.toml)
You can now persistently configure cargo-dist with [workspace.metadata.dist]
in your root Cargo.toml, with the ability to override some settings per-package with [package.metadata.dist]
.
The following settings can only be set in [workspace]
:
- cargo-dist-version: (Cargo SemVer format) specifies the desired version of cargo-dist for building the project. Currently only used when generating CI scripts. When you run
cargo dist init
the version you're using will be set here. If omitted, every time you runcargo dist generate-ci
it will just bake in the version of cargo dist you are currently locally running. - rust-toolchain-version: (rustup toolchain format) species the desired version of rust/cargo for building the project. Currently only used when generating CI scripts. When you run
cargo dist init
we currently just select a hardcoded stable release (1.67.1). If omitted we will just select the "stable" toolchain (which will drift over time). - ci: a list of CI backends to support (currently only
["github"]
will work). This is used bycargo dist generate-ci
so you no longer need to pass the flag every time. It's also used to detect the format to use for download URLs (for things like installer scripts).
The following settings can be set on either [workspace]
or [package]
, with the latter overriding the former:
- dist: (bool, defaults to "undefined") whether this package's binaries should be visible to cargo-dist for the purposes of Releases. If undefined, we will defer to cargo's own publish=false config. Packages without binaries are always invisible to cargo-dist.
- installers: (list of installer kinds) the default set of installers to generate for releases (currently only "github-shell" and "github-powershell" are defined)
- targets: (list of rust-style target-triples) the default set of targets to use for releases (sort of, see the section on CLI configuration)
- include: (list of paths relative to that Cargo.toml's dir) extra files to include in executable-zips (does not currently support directories or wildcards, individual files only)
- auto-includes: (bool, defaults true) whether dist should add README/LICENSE/etc files to your executable-zips when it finds them.
Configuration (Artifact CLI flags)
Previously cargo-dist had some vague notions of what it was supposed to do when you invoked it, because there were platform-specific artifacts like executable-zips but also more platform-agnostic ones like installer scripts. This result in flags like --no-builds
with messy semantics and hacks to filter out artifacts we "don't want right now" in the CI scripts (--no-builds
was is removed in this release, it was busted).
Now cargo-dist can produce well-defined subsets of the all possible artifacts with the --artifacts
flag:
--artifacts = "local" | "global" | "all" | "host"
Artifacts can be broken up into two major classes:
- local: made for each target system (executable-zips, symbols, MSIs...)
- global: made once (curl-sh installers, npm package, metadata...)
("all" selects both of these at once)
Having this distinction lets us run cargo-dist independently on multiple machines without collisions between the outputs by spinning up machines that run something like:
- linux-runner1 (get full manifest): cargo-dist manifest --artifacts=all --output-format=json
- linux-runner2 (get global artifacts): cargo-dist --artifacts=global
- linux-runner3 (get linux artifacts): cargo-dist --artifacts=local --target=x86_64-unknown-linux-gnu
- windows-runner (get windows artifacts): cargo-dist --artifacts=local --target=x86_64-pc-windows-msvc
If let unspecified, we will pick a fuzzier "host" mode that builds "as much as possible" for the local system. This mode is appropriate for local testing/debugging/demoing. If no --target flags are passed on the CLI then "host" mode will try to intelligently guess which targets to build for, which may include building targets that aren't defined in your metadata.dist config (since that config may exclude the current machine!).
The specifics of "host" mode are intentionally unspecified to enable us to provider better out-of-the-box UX for local usage. In CI environments you should always specify one of the other tree options!
Note that the introduction of persistent Cargo.toml configuration is crucial to this semantic redesign, as it allows each invocation to be aware of the "full" set of artifacts across all platforms, and then filter down to it.
If you pass --installer
, --ci
, or --target
this will replace the Cargo.toml value for all packages for that invocation. This is most useful for --target
in conjuction with --artifacts=local
as it lets us precisely select which platform-specific artifacts to build on the current machine (all 3 of these flags can be passed repeatedly).
WARING! If you specify --artifacts and --target, the selected targets can only be a subset of the ones defined in your Cargo.toml. This ensures cargo dist --artifacts=global
has behaviour consistent with cargo dist --artifacts=local --target=...
, as global artifacts need to be aware of all targets at once. "host" mode bypasses this restriction so that runs of cargo dist on developer machines can do something useful even if the Cargo.toml doesn't know about the host platform.
Configuration (Announcement/Release Selection)
There is also now a --tag
flag for specifying the git tag to use for announcing a new release. This tag must have a specific format detailed below. The tag serves two purposes:
- It specifies the subset of the workspace that we want to Announce/Release
- When using CI, it becomes the unique ID for a Github Release, which is necessary for everything to correctly compute download URLs
cargo dist build
and cargo dist manifest
now both require that you either specify a --tag that "makes sense", or that your workspace is simple enough for a tag to be computed for you. In CI, each git tag you push will create an independent run of cargo-dist's CI to make a Github Release for that tag, and each invocation of cargo-dist will have that tag passed to it, ensuring they all agree on the above details.
There are two kinds of tag formats that are accepted:
- Unified Announcement:
v{VERSION}
selects all packages with the given version (v1.0.0, v0.1.0-prerelease, etc.) - Singular Announcement:
{PACKAGE-NAME}-v{VERSION}
selects only the given package (error if the version doesn't match)
Note that other criteria may prevent a package from being selected: it has no binaries, it has dist=false, it has publish=false, etc. If you do not specify a --tag, cargo-dist will check if all still-selectable packages share a version, and if they do it will make a Unified Announcement for them (erroring otherwise).
These two modes support the following workflow:
- Releasing a workspace with only one binary-having package (either mode works but Unified is Cleaner)
- Releasing a workspace where all binary-having packages are versioned in lockstep (Unified)
- Releasing an individual package in a workspace with its own independent versioning (Singular)
- Releasing several packages in a workspace at once, but all independently (Push multiple Singular tags at once)
Basically the one thing we can't deal with is you saying "I would like a single coherent Announcement (Github Release) for packageA 0.1.0 and packageB 0.2.0", because nothing really ties them together. If you disagree, please let us know how you think it can/should work!
Although you could use extremely careful versioning in conjuction with Unified Announcements to release a weird subset of the packages in your workspace, you really shouldn't because the Github Releases will be incoherent (v0.1.0 has these random packages, v0.2.0 has these other random packages... huh?), and you're liable to create painful tag collisions.
WARNING! cargo-release largely already generates tags that express these exact semantics, except for one annoying corner case (that I've found so far): if ...
Version 0.0.3-prerelease01 (still being tested!!!)
Install
Install prebuilt binaries via shell script
# WARNING: this installer is experimental
curl --proto '=https' --tlsv1.2 -L -sSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.3-prerelease01/installer.sh | sh
Install prebuilt binaries via powershell script
# WARNING: this installer is experimental
irm 'https://github.com/axodotdev/cargo-dist/releases/download/v0.0.3-prerelease01/installer.ps1' | iex
Download
target | kind | download |
---|---|---|
x86_64-unknown-linux-gnu | tarball | cargo-dist-v0.0.3-prerelease01-x86_64-unknown-linux-gnu.tar.xz |
x86_64-apple-darwin | tarball | cargo-dist-v0.0.3-prerelease01-x86_64-apple-darwin.tar.xz |
x86_64-pc-windows-msvc | tarball | cargo-dist-v0.0.3-prerelease01-x86_64-pc-windows-msvc.zip |
x86_64-pc-windows-msvc | symbols | cargo-dist-v0.0.3-prerelease01-x86_64-pc-windows-msvc.pdb |
Release Notes
USE AT YOUR OWN RISK, SUPER ALPHA
A major overhaul has been done to the design to rationalize some improperly defined features/behaviours, when you update to this version you will need to rerun cargo dist init
(and need to generate-ci).
Configuration (Cargo.toml)
You can now persistently configure cargo-dist with [workspace.metadata.dist]
in your root Cargo.toml, with the ability to override some settings per-package with [package.metadata.dist]
.
The following settings can only be set in [workspace]
:
- cargo-dist-version: (Cargo SemVer format) specifies the desired version of cargo-dist for building the project. Currently only used when generating CI scripts. When you run
cargo dist init
the version you're using will be set here. If omitted, every time you runcargo dist generate-ci
it will just bake in the version of cargo dist you are currently locally running. - rust-toolchain-version: (rustup toolchain format) species the desired version of rust/cargo for building the project. Currently only used when generating CI scripts. When you run
cargo dist init
we currently just select a hardcoded stable release (1.67.1). If omitted we will just select the "stable" toolchain (which will drift over time). - ci: a list of CI backends to support (currently only
["github"]
will work). This is used bycargo dist generate-ci
so you no longer need to pass the flag every time. It's also used to detect the format to use for download URLs (for things like installer scripts).
The following settings can be set on either [workspace]
or [package]
, with the latter overriding the former:
- dist: (bool, defaults to "undefined") whether this package's binaries should be visible to cargo-dist for the purposes of Releases. If undefined, we will defer to cargo's own publish=false config. Packages without binaries are always invisible to cargo-dist.
- installers: (list of installer kinds) the default set of installers to generate for releases (currently only "github-shell" and "github-powershell" are defined)
- targets: (list of rust-style target-triples) the default set of targets to use for releases (sort of, see the section on CLI configuration)
- include: (list of paths relative to that Cargo.toml's dir) extra files to include in executable-zips (does not currently support directories or wildcards, individual files only)
- auto-includes: (bool, defaults true) whether dist should add README/LICENSE/etc files to your executable-zips when it finds them.
Configuration (Artifact CLI flags)
Previously cargo-dist had some vague notions of what it was supposed to do when you invoked it, because there were platform-specific artifacts like executable-zips but also more platform-agnostic ones like installer scripts. This result in flags like --no-builds
with messy semantics and hacks to filter out artifacts we "don't want right now" in the CI scripts (--no-builds
was is removed in this release, it was busted).
Now cargo-dist can produce well-defined subsets of the all possible artifacts with the --artifacts
flag:
--artifacts = "local" | "global" | "all" | "host"
Artifacts can be broken up into two major classes:
- local: made for each target system (executable-zips, symbols, MSIs...)
- global: made once (curl-sh installers, npm package, metadata...)
("all" selects both of these at once)
Having this distinction lets us run cargo-dist independently on multiple machines without collisions between the outputs by spinning up machines that run something like:
- linux-runner1 (get full manifest): cargo-dist manifest --artifacts=all --output-format=json
- linux-runner2 (get global artifacts): cargo-dist --artifacts=global
- linux-runner3 (get linux artifacts): cargo-dist --artifacts=local --target=x86_64-unknown-linux-gnu
- windows-runner (get windows artifacts): cargo-dist --artifacts=local --target=x86_64-pc-windows-msvc
If let unspecified, we will pick a fuzzier "host" mode that builds "as much as possible" for the local system. This mode is appropriate for local testing/debugging/demoing. If no --target flags are passed on the CLI then "host" mode will try to intelligently guess which targets to build for, which may include building targets that aren't defined in your metadata.dist config (since that config may exclude the current machine!).
The specifics of "host" mode are intentionally unspecified to enable us to provider better out-of-the-box UX for local usage. In CI environments you should always specify one of the other tree options!
Note that the introduction of persistent Cargo.toml configuration is crucial to this semantic redesign, as it allows each invocation to be aware of the "full" set of artifacts across all platforms, and then filter down to it.
If you pass --installer
, --ci
, or --target
this will replace the Cargo.toml value for all packages for that invocation. This is most useful for --target
in conjuction with --artifacts=local
as it lets us precisely select which platform-specific artifacts to build on the current machine (all 3 of these flags can be passed repeatedly).
WARING! If you specify --artifacts and --target, the selected targets can only be a subset of the ones defined in your Cargo.toml. This ensures cargo dist --artifacts=global
has behaviour consistent with cargo dist --artifacts=local --target=...
, as global artifacts need to be aware of all targets at once. "host" mode bypasses this restriction so that runs of cargo dist on developer machines can do something useful even if the Cargo.toml doesn't know about the host platform.
Configuration (Announcement/Release Selection)
There is also now a --tag
flag for specifying the git tag to use for announcing a new release. This tag must have a specific format detailed below. The tag serves two purposes:
- It specifies the subset of the workspace that we want to Announce/Release
- When using CI, it becomes the unique ID for a Github Release, which is necessary for everything to correctly compute download URLs
cargo dist build
and cargo dist manifest
now both require that you either specify a --tag that "makes sense", or that your workspace is simple enough for a tag to be computed for you. In CI, each git tag you push will create an independent run of cargo-dist's CI to make a Github Release for that tag, and each invocation of cargo-dist will have that tag passed to it, ensuring they all agree on the above details.
There are two kinds of tag formats that are accepted:
- Unified Announcement:
v{VERSION}
selects all packages with the given version (v1.0.0, v0.1.0-prerelease, etc.) - Singular Announcement:
{PACKAGE-NAME}-v{VERSION}
selects only the given package (error if the version doesn't match)
Note that other criteria may prevent a package from being selected: it has no binaries, it has dist=false, it has publish=false, etc. If you do not specify a --tag, cargo-dist will check if all still-selectable packages share a version, and if they do it will make a Unified Announcement for them (erroring otherwise).
These two modes support the following workflow:
- Releasing a workspace with only one binary-having package (either mode works but Unified is Cleaner)
- Releasing a workspace where all binary-having packages are versioned in lockstep (Unified)
- Releasing an individual package in a workspace with its own independent versioning (Singular)
- Releasing several packages in a workspace at once, but all independently (Push multiple Singular tags at once)
Basically the one thing we can't deal with is you saying "I would like a single coherent Announcement (Github Release) for packageA 0.1.0 and packageB 0.2.0", because nothing really ties them together. If you disagree, please let us know how you think it can/should work!
Although you could use extremely careful versioning in conjuction with Unified Announcements to release a weird subset of the packages in your workspace, you really shouldn't because the Github Releases will be incoherent (v0.1.0 has these random packages, v0.2.0 has these other random packages... huh?), and you're liable to create painful tag collisions.
WARNING! cargo-release largely already generates tags that express these exact semantics, except for one annoying corner case (that I've found so far): if you have a non-virtual workspace (th...
Version 0.0.2 (2023-01-31)
Install
Install prebuilt binaries via shell script
# WARNING: this installer is experimental
curl --proto '=https' --tlsv1.2 -L -sSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.2/installer.sh | sh
Install prebuilt binaries via powershell script
# WARNING: this installer is experimental
irm 'https://github.com/axodotdev/cargo-dist/releases/download/v0.0.2/installer.ps1' | iex
Download
target | kind | download |
---|---|---|
x86_64-unknown-linux-gnu | tarball | cargo-dist-v0.0.2-x86_64-unknown-linux-gnu.tar.xz |
x86_64-apple-darwin | tarball | cargo-dist-v0.0.2-x86_64-apple-darwin.tar.xz |
x86_64-pc-windows-msvc | tarball | cargo-dist-v0.0.2-x86_64-pc-windows-msvc.zip |
x86_64-pc-windows-msvc | symbols | cargo-dist-v0.0.2-x86_64-pc-windows-msvc.pdb |
Release Notes
cargo-dist:
- Added proper detection of README/LICENSE/RELEASES/CHANGELOG files, which are now copied to the root of executable-zips.
- We will defer to Cargo fields like "readme" and "license-file" if present
- Otherwise we will search the root directory of the package and the root directory of the workspace (preferring results from the former)
- Release note handling:
- --ci=github will manually set the title and body of the Github Release
- The body is a generated listing of installers/downloads
- If your RELEASES/CHANGELOG parses with parse_changelog library we'll append the current release's notes to the body, and use the heading for the title
- If we don't parse your RELEASES/CHANGELOG we will default to a title of "v{VERSION}"
cargo-dist-schema:
- Changed PathBufs to Strings since the paths may be from a different OS and Rust Paths are generally platform-specific. Seemed like a ticking timebomb for some weird corner case.
- Added "changelog" as a valid AssetKind
- Added "changelog_title" and "changelog_body" to Release
- These are used to populate a Github Release
- Added "description" to Artifact
- Currently just used to describe some installers
- Made Artifact::name Optional to futureproof
- If None this indicates the artifact is purely informative and no file exists (i.e. "you can install with cargo-binstall")
v0.0.2-prerelease02
Install
Install prebuilt binaries via shell script
# WARNING: this installer is experimental
curl --proto '=https' --tlsv1.2 -L -sSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.2-prerelease02/installer.sh | sh
Install prebuilt binaries via powershell script
# WARNING: this installer is experimental
irm 'https://github.com/axodotdev/cargo-dist/releases/download/v0.0.2-prerelease02/installer.ps1' | iex
Download
target | kind | download |
---|---|---|
x86_64-unknown-linux-gnu | tarball | cargo-dist-v0.0.2-prerelease02-x86_64-unknown-linux-gnu.tar.xz |
x86_64-apple-darwin | tarball | cargo-dist-v0.0.2-prerelease02-x86_64-apple-darwin.tar.xz |
x86_64-pc-windows-msvc | tarball | cargo-dist-v0.0.2-prerelease02-x86_64-pc-windows-msvc.zip |
x86_64-pc-windows-msvc | symbols | cargo-dist-v0.0.2-prerelease02-x86_64-pc-windows-msvc.pdb |
v0.0.2-prerelease01
chore: Release cargo-dist-schema version 0.0.2-prerelease01
v0.0.1
chore: Release cargo-dist-schema version 0.0.1
v0.0.1-prerelease2
chore: Release cargo-dist-schema version 0.0.1-prerelease2