Skip to content

Latest commit

 

History

History

docs

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

README.md

Create Julia Distribution

Three composable actions for turning a Julia project into a relocatable Julia distribution: a self-contained tree holding a Julia runtime, a system image with the project's dependencies baked into it, and those dependencies exposed as standard libraries. Someone who unpacks it gets a julia that can start using the project without resolving, installing or compiling anything.

Action What it does
create-julia-distribution Builds the distribution from a project.
create-julia-distribution/pack Packs a built distribution into a gzipped tarball.
create-julia-distribution/sign-macos Signs the Mach-O binaries and bundles in a built macOS distribution.

What these actions do not do

An action called "create a Julia distribution" that neither installs Julia nor publishes anything is worth reading as composable rather than as unfinished. It covers the build and nothing around it:

  • It does not install Julia. A julia on PATH is what the distribution is built with and what determines the runtime version it ships, so installing it is where a caller chooses that version.
  • It does not set up private registries or hold credentials. Dependencies resolving from the default registries need nothing, since Pkg provisions General itself while instantiating the project. Anything beyond that — a package server, a private registry, an SSH key — is arranged by the caller in a preceding step. No input takes a token.
  • It does not sign anything. The macOS signing action is a separate call the caller makes on the built tree; signing for other runners, notarization and stapling are the caller's own steps entirely.
  • It does not publish anything. Nothing is uploaded, tagged or released; the distribution is left in the workspace for the caller to do something with.
  • It does not test the result. The built tree contains a working julia, and running anything against it is a step the caller adds.
  • It does not cache your dependencies. Every run resolves and builds from scratch unless the caller arranges a warm depot itself.

Build, then your own steps, then pack

Building and packing are two actions rather than one so that the interval between them exists. The build leaves an unpacked directory in the workspace and reports its path; anything done to a distribution — signing it, pruning it, rewriting something in it, measuring it, running a test suite against it — is a step the caller puts in that interval, operating on the tree in place. Packing then turns whatever the tree has become into a tarball.

- uses: "JuliaComputing/create-julia-distribution@958799562b82fcabd2f5508f7ee296e1d91de200" # build
- run: "..." # your steps
- uses: "JuliaComputing/create-julia-distribution/pack@958799562b82fcabd2f5508f7ee296e1d91de200" # pack

Calling the two back to back with nothing in between is complete and supported; the minimum example does exactly that.

Important

Anything sensitive that a build can reach is at risk during it. Building a system image runs code from the project and its dependencies — precompilation, module initialization and whatever else is evaluated while the image is created — and that code runs with everything the job has: the environment, the filesystem, the network. A token in an environment variable, a credential file an earlier step wrote, a signing key materialized before the build, a cloud credential from an assumed role: a dependency you did not write can read any of it, exfiltrate it, or sign with it.

This is not hypothetical hardening. Building a distribution means executing your whole dependency tree, so treat the build as a place where third-party code runs with your job's privileges, and grant it only what resolving and building genuinely need.

Everything else belongs in the interval after the build, which is where the signing example writes its signing certificate.

Where to go next