[HN Gopher] Release engineering is exhausting so here's cargo-dist ___________________________________________________________________ Release engineering is exhausting so here's cargo-dist Author : ag_dubs Score : 129 points Date : 2023-02-01 17:50 UTC (5 hours ago) (HTM) web link (blog.axo.dev) (TXT) w3m dump (blog.axo.dev) | ZeroCool2u wrote: | "Alright so I've given you The Pitch of how this should work, but | how does it actually work today? Well, yes, I wouldn't announce | this if not -- but there's a lot of future work to do! Actually | no I take that back, it's definitely perfect. Those familiar with | my broader oeuvre know this will absolutely be a perfectly | crafted demo that avoids all the sharp corners of cargo-dist!" | | One of the most honest paragraphs ever written. | | Seriously though, great tool and great write up. I hope something | like this lands as an official cargo feature. Coming from mostly | Python land at work with crazy dependencies for TF and PyTorch | GPU support (On Windows sometimes!) makes me super jealous. | chatmasta wrote: | I'm really not a fan of the "download the prebuilt binary from | github releases" workflow that's been proliferating along with | the popularity of Rust. It seems like a step backward in terms of | secure package management, and it's surprising to me that Rust | doesn't offer a more out-of-box experience for this, instead | encouraging users to build from source. I understand the | arguments for this, and I even find some of them convincing - | namely, that the inverse problem of opaque intermediate binaries | and object files would be much worse as it would cause a cascade | of brittle builds and barely any packages would work. | | But the fact remains that end users want to download a binary, | and the common approach to this is to simply publish them to | GitHub actions. Surely Cargo could offer a better option than | this, while retaining the ability to build all packages from | source (maybe you can only publish binaries to Cargo _in | addition_ to the source files... or maybe Cargo.toml could | include a link to GitHub releases, and Cargo could include a | command for downloading directly from there.) | | In the meantime, I've been considering publishing Rust binaries | to npm (in addition to GitHub releases). I got the idea from | esbuild, which is written in Go but distributed via npm. What do | people think of this approach? Here's a recent blog post [0] | describing the setup. | | [0] https://blog.orhun.dev/packaging-rust-for-npm/ | ag_dubs wrote: | we actually agree and are working on this! github releases are | just an easy initial target, and makes our tool a drop-in | replacement for the kinds of things people are already doing. | longer-term we'd like to see something more robust, and cargo- | dist is the first cog in that machine. | | i have personally packaged and published many rust devtools on | npm (cloudflare's wrangler, apollo's rover, wasm-pack) but that | was largely because they were targeted at a javascript | developer audience. | | as a former npm registry engineer i'm curious what you find to | be the particular value of publishing to npm? installing node | is actually very unpleasant and then getting global installs to | work is also... very unpleasant. i think it works well for | people already in that ecosystem but i think we can build | something better for a more agnostic audience that can give a | similar out-of-box exp without requiring a centralized | registry. would love to learn more about your perspective! | simonw wrote: | I've noticed people publishing binaries to PyPI too - you can | run "pip install ziglang" to get Zig, for example. | | I wrote a bit about that pattern here: | https://simonwillison.net/2022/May/23/bundling-binary-tools-... | jacoblambda wrote: | Worth considering using nix with cargo. Of course it still | involves a lot of "download from github" or "download from nix | cache" but reproducibility + tight source hash pinning helps | guarantee provenance. | Shared404 wrote: | > (Did you know the warning you get on Windows isn't about code | signing, but is actually just a special flag Windows' builtin | unzipping tool sets on all executables it extracts?) | | My jaw hit the floor here. | Gankra wrote: | Correction on this someone else sent me: | | The check of interest is for a Mark Of The Web[0] flag that | Windows includes in file system metadata. The builtin unzipping | utility just faithfully propagates this flag to the files it | unpacks. Other utilities like 7zip are unlikely to do this | propagation (effectively clearing it). | | But yeah either way it has nothing to do with code signing! | | [0]: https://nolongerset.com/mark-of-the-web-details/ | jakub_g wrote: | If someone's interested with more details about MoTW, EricLaw | (long time MSFT engineer at IE and Edge teams) got you | covered: | | https://textslashplain.com/2016/04/04/downloads-and-the- | mark... | | https://textslashplain.com/2022/12/02/mark-of-the-web- | additi... | chatmasta wrote: | macOS has a similar feature with Gatekeeper, which bit me | when preparing a Pyinstaller binary for Mac. The flag doesn't | get added when you download a file with curl, but it does | when you download it through a web browser, which can cause | difficult to debug issues with binaries downloaded from | GitHub releases. | | You can remove this flag with the xattr command: | xattr -d com.apple.quarantine the_quarantined_binary | | I wrote up the details of this in a PR [0] where I last dealt | with it. | | [0] https://github.com/splitgraph/sgr/pull/656 | maldev wrote: | This is actually pretty similar. The OS has an alternative | data stream(An idea they stole from Mac), and they list | what site a exe was downloaded on, or if it came from | somewhere else. Others incorrectly called it a flag, when | it works by having two different file data streams for a | single file, one is the default one. | | So for example, a single file can actually contain two | different "files"(File data). | | So, foo.exe, actually will effectively open the file | foo.exe:DEFAULT. You could also add a piece of malware to | the foo file in place of a datastream. So foo.exe is legit, | but if you open foo.exe:MALWARE , it will open up the | malware datastream. | | So tldr, how Windows does this, it when you get a file from | a third party source(Internet, USB Drive, etc), it adds a | new datastream in the form of a textfile. And the textfile | contains info about the source. Namely, a number for | location it came from(3? for web), and then some more info. | jph wrote: | Awesome thank you. I'm adding it to the cargo favorites list: | https://github.com/sixarm/cargo-install-favorites | | Tiny feedback: | | - Can you consider changing "git add ." to be explicit e.g. "git | add Cargo.toml .github/workflows/release.yml"? | | - How about modifying Cargo.toml to add cargo-dist as a dev- | dependency? I know it's not strictly necessary; it's just very | helpful for typical collaboration. | Gankra wrote: | Do you mean this kind of dep? https://rust- | lang.github.io/rfcs/3028-cargo-binary-dependenc... | | That's an interesting thought, I'm not sure I've ever seen | someone employ that as a pattern. Actually no wait, I thought | cargo bin-deps specifically gave the developer no way to | manually invoke it (i.e. there's no equivalent functionality to | npm's npx)? Without that, what use would the dependency be? | jph wrote: | Yes, where that link describes "[dev-dependencies]" and | "[build-dependencies]". | | I use the dev-dependencies section often, and the build- | dependencies rarely. And anyone here, please correct my | understanding if there's a better way to do what I'm | describing. | | For me, these sections are an easy way to be explicit with | collaborators that the project needs the deps installed in | order to work on the project, and does not want/need the deps | to be compiled into the release. | | My #1 use case is to have a collaborator start with a git | clone, then run "cargo build", and have cargo download and | cache everything that's needed to work on the project and | release it. My #2 use case is to deal with semver, so a | project can be explicit that it needs a greater cargo-dist | version in the future. | | To your point about cargo bin deps akin to npx, yes, your | understanding matches mine i.e. not available yet. I do | advocate for that feature to be added because it's helpful | for local environments. Cargo does offer "default-run" which | shows there an awareness of a developer preferring specific | local exectuables-- maybe Cargo can/will add more like that | for deps? | IshKebab wrote: | > Congrats kid you're A Release Engineer now and your life is | hell. Enjoy debugging basic typos on a remote machine with 20 | minute latency because you sure can't run those Github CI bash- | scripts-in-yaml files locally! | | Yes! Why is this accepted?? | | Gitlab has a way of running CI locally (for Docker based builds | anyway; who knows about Windows or Mac) but a) it doesn't support | the same features at the "proper" one (even basic ones like the | `default` key) and b) they deprecated it! | | Ok in fairness they've stated in a random comment that they won't | remove it before providing an alternative.... But still, how is | this not a core feature of all CI systems? | sedatk wrote: | You can run GitHub workflows locally with act: | https://github.com/nektos/act | frodowtf wrote: | Act is okay, but the runner image behaves quite differently | than a GitHub runner would. The original image would just be | too big for reasonable local workflows. | | Also artifacts don't seem to be supported. | ollien wrote: | This is far from perfect, IME. The big problem I have (and | maybe there's a solution I don't know about) is that there's | no easy way to test getting event data, unless you wanna | rebuild the events yourself (which is hardly reliable if the | problem is something like verifying a conditional that | enables/disables a stage). | adrienthebo wrote: | Seconding this; act has a lot of potential but misses a | number of features such as support for deployment | environment variables (eg `${{ var.DEPLOY_SPECIFIC_ENV_VAR | }}`) and only recently added support for reusable workflows | (https://github.com/nektos/act/issues/826). It looks like | fine software and the maintainers deserve praise for their | work but it's not yet a drop-in replacement for GitHub | Actions. | wizzwizz4 wrote: | > _But still, how is this not a core feature of all CI | systems?_ | | Vendor lock-in, presumably. | WorldMaker wrote: | In multiple directions, too. It's easier to build the CI | system itself if you are only targeting one class of | servers/one means of hosting servers/one specific "cloud". | capableweb wrote: | CircleCI solved this so many years ago, allow users to SSH into | the environment the build happens. | | Workflow is something like: | | - Guess together a random CI or CD workflow, this is just to | kick off the process. You can also start with a empty config. | | - Something fails, get SSH host+port to connect to | | - Enter environment and manually do everything you want to be | able to automatically do | | - Execute `history` and copy output, trim it into something | nicer and put in your config | angio wrote: | If you're using nix to build your repo, it's worth adding | scripts for releases etc and run them locally and as part of | the ci https://determinate.systems/posts/nix-github-actions | brundolf wrote: | What we need is a standard CI language/config format across | vendors (stuffing a custom DSL inside YAML doesn't count) | | That would allow for a tooling ecosystem of static checkers, | offline runners, IDE integrations, etc etc, and would also cut | down on the learning barrier every time you switch to a new | company that uses a different vendor | samsquire wrote: | There's so much work to do to release software. Kind of explains | why everything is a website. | oconnor663 wrote: | Bend the curve! | MuffinFlavored wrote: | I think this would benefit from an example repo that shows just | Cargo.toml for a simple src/main.rs with `fn main() { | println!("Hello, world!"); }` project with the simplest needed | .github/workflows/foo.yaml possible to actually use this. | | If it was in the article and I missed it I apologize. | Gankra wrote: | The "way-too-quickstart" is the minimal example: | https://github.com/axodotdev/cargo-dist#way-too-quick-start | | A key feature of cargo-dist is that | | cargo dist init --ci=github | | should simply set everything up for an arbitrary* Rust | workspace and you just check in the results. | | * Not sufficiently tested for all the wild workspaces you can | build, but a "boring" one with a bunch of libraries supporting | one binary should work -- that's what cargo-dist's own | workspace is, and it's self-hosting without any configuration. | Any time I want to update the bootstrap dist I just install | that version of cargo-dist on my machine and run `cargo dist | generate-ci github --installer=...` to completely overwrite the | ci with the latest impl. | Gankra wrote: | Just to elaborate on this a bit: as discussed in the Concepts | section of the docs[0] the core of cargo-dist absolutely | supports workspaces with multiple binaries, and will chunk | them out into their own distinct logical applications and | provide builds/metadata for all them. | | However this isn't fully supported by the actual github CI | integration yet[1], as I haven't implemented proper support | for detecting that you're only trying to publish a new | version of _only one_ of the applications (or none of them!), | and it doesn 't properly merge the release notes if you're | trying to publish multiple ones at once. | | I never build workspaces like that so I'm waiting for someone | who _does_ to chime in with the behaviour they want (since | there 's lots of defensible choices and I only have so many | waking hours to implement stuff). | | [0]: https://github.com/axodotdev/cargo-dist/#concepts [1]: | https://github.com/axodotdev/cargo-dist/issues/69 | MuffinFlavored wrote: | Cool, thanks. | | It creates a ~100 line release.yml file | | 1. create GitHub release | | 2. upload artifacts | | 3. upload manifest | | 4. publish GitHub release | | I like it, it's opinionated, but I don't know how much it | will catch on. If somebody needs to maintain a 100 line | GitHub Actions release YAML file, in my experience you | typically want to understand everything in it in case you | need to adjust it for future needs/as they grow. | | It's well done though. Curious to see how much adoption it | picks up. | Chmouel wrote: | i really enjoy goreleaser | https://github.com/goreleaser/goreleaser/ and use it with rust | https://github.com/chmouel/snazy/blob/main/.goreleaser.yaml#... | combined with build matrix | https://github.com/chmouel/snazy/blob/main/.github/workflows... | ag_dubs wrote: | definitely inspired by goreleaser! it's a great project ___________________________________________________________________ (page generated 2023-02-01 23:00 UTC)