I’ve previously outlined my reasons for evaluating Rust and Deno. Using these technologies, I am looking to achieve:
- A scriptable high-level layer (Deno REPL) controlling a performant lower-level core (Rust).
- A single executable binary via Deno Compile.
- Cross platform executables via cross-compilation support for Deno and Rust.
- Agnostic support for running as an OS process or in a browser runtime via Deno’s web platform APIs and the ability to compile Rust to WASM.
- Simple project scaffolding via Deno’s stated goal to “provide built-in tooling to improve developer experience”.
I wanted to see if these could all be achieved using free SaaS tooling for continuous integration including:
- code analysis
- automated dependency updates
- automated unit testing and integration/acceptance testing
- automated semantic releases
- automatically generated API documentation
I created the template projects and GitHub workflow and actions discussed here to see if the technologies could deliver on their promises and thus achieve my aims.
I should state that I defaulted to using GitHub simply because I have been using it for several years now. Beyond recent FOSS concerns in the news I haven’t discovered any functional deficiencies which have caused me to look elsewhere.
Before getting into details (and the inevitable pain points), some of the feature highlights I’ve managed to achieve are:
- A single executable available for Linux, MacOS and Windows with the same functionality also running in a browser.
- Instrumented test coverage analysis
- Working example projects with GitHub actions for testing, compiling, versioning and releasing for:
- Rust + Deno via FFI Bindings
- Rust + Deno via WASM
- Automated PRs, testing, merging, versioning and releasing for internal and 3rd party dependencies
- Automatically updated API documentation
The GitHub repositories involved in this effort are as follows:
- flowscripter/template-deno-executable: Project template for a Deno executable.
- flowscripter/template-deno-webapp: Project template for a Deno based webapp with Deno and Rust based WASM library dependencies.
“Simple Library” Projects
- flowscripter/template-deno-library: Project template for a Deno library.
- flowscripter/template-rust-library: Project template for a Rust library.
“Glue Library” Projects
- flowscripter/template-deno-rust-library: Project template for a Rust library with Deno FFI bindings.
- flowscripter/template-wasm-rust-library: Project template for a Rust library compiled to WASM.
- flowscripter/template-deno-wasm-rust-library: Project template for a Rust library compiled to WASM exposed as a Deno module.
- flowscripter/.github: GitHub Actions and Workflow Templates
A picture is worth a 1000 words… or maybe its just confusing…
It’s big and complex, but I hope the following describes things visually. It shows the projects (together with their artifacts and inter-dependencies) and various good and bad things to note.
Click on it to open in a larger form.
Eclectic Mix of Workarounds
Beyond some outstanding issues outlined further below, there were a few things I discovered which are worth noting:
.github v1 branch
As far as I am aware, the best approach to managing versioning of GitHub Actions in your own
.github repository without publishing them
is to use branches for versioning.
Each time I push a new commit to flowscripter/.github which involves an Action fix, I re-create the branch
v1 on the
.github repository so that the updated Action implementation will be used by dependent repositories.
As an example, the reference to the Action
release_deno_library in the template-deno-library project is:
GitHub Pages to host WASM library releases
I used GitHub Pages to host a demo of the webapp.
- These require opting back into the NodeJS+NPM package ecosystem (something I was trying to opt OUT OF by using Deno)
- It seemed there was nothing available which supported serving WASM files with the mime-type expected by Deno when it fetches WASM files within the modules created with wasm-pack.
Reliance on Node and NPM
The semantic-release project is excellent.
However it is written using Node and NPM. I’d love to find GitHub Actions which fully wrap this functionality or a
single executable which doesn’t require an
npm install which kind of goes against the grain when trying to migrate to Deno…
Following on from this, the semantic release plugin @qiwi/semantic-release-gh-pages-plugin expects the project being released to be
Node based and therefore expects a
package.json file to exist in the repository.
Therefore, as part of releasing a WASM compiled library to GitHub pages, I need to:
- perform an
npm installso that the
- remove the generated
package.jsonBEFORE the semantic-release-rust tool is used to perform a Cargo publish (Cargo doesn’t like files which aren’t in Git when publishing).
The fact that this is a workaround for publishing to GitHub Pages which is in itself a workaround for hosting WASM library releases really does bite…
Git Update of Main Branch
I wanted to apply branch permissions for ALL users, including administrators of the repositories.
However, for Rust based repositories, the release number needs to be set in the
cargo.toml file when performing the release from the
To achieve this, I needed the GitHub Action to be able to push directly to the
Thus I needed a Personal Access Token which will only work if administrators (i.e. myself) ARE NOT included in branch permissions…
Whilst writing this blog entry, the Actions making use of deno_bindgen stopped working due to this issue:
If you play with unstable APIs you’re gonna get hurt…
The items I discovered which are blockers for my stated aims are as follows:
Deno Compile support for dynamic imports
- compilation to a single binary executable
However it doesn’t support both of these at the same time: https://github.com/denoland/deno/issues/8655
deno_bindgen updated to support the latest unstable Deno API
I mentioned this earlier as a downside to being on the bleeding edge: https://github.com/denoland/deno_bindgen/issues/80
Automatic Rust API docs for projects using
Glue technologies like deno_bindgen are excellent, however I seem to be ‘stuck’ with this: https://github.com/denoland/deno_bindgen/issues/72
Deno signing and notarisation support
It’s not great delivering a single binary executable if the OS is reticent to run it… https://github.com/denoland/deno/issues/11154
GitHub Actions support for Apple Silicon
Not major, but until this is available I can’t fully implement cross-platform CI: https://github.com/actions/virtual-environments/issues/2187
If anyone is interested in this and has actually read this far, I would love some feedback on:
- suggested improvements or recommendations
- any issues discovered