Skip to content

Flutter

Download Conveyor

macOS

After dragging to your Applications folder open the Conveyor app and click "Add to path" in the UI.

Create a sample project

  • Create a new Flutter project, either with your IDE or with the CLI (flutter create my_project).
  • Change the version to remove the build number (the +1 after the version). Version numbers aren't allowed to have + symbols in them in most operating system packaging formats.

Now let's build it:

flutter build windows --release
flutter build macos --release
flutter build linux --release

Important

If you share your source directory between platforms e.g. using a virtual machine mount, you may need to run flutter clean when switching between different operating systems.

  • Install the yq tool by Mike Farah. We'll use it to import config from the pubspec.yaml file.
  • Create a file called conveyor.conf in the root of your project:
include required("/stdlib/flutter/flutter.conf")

pubspec {
  include required("#!yq -o json pubspec.yaml")
}

app {
  # 💥 EDIT THESE NEXT 4 LINES!!! 💥
  display-name = My Project
  fsname = my-project
  rdns-name = com.example.MyProject
  vendor = SuperOrg

  version = ${pubspec.version}
  description = ${pubspec.description}

  site.base-url = "localhost:3000"
  updates = aggressive

  windows.amd64.inputs += build/windows/runner/Release
  linux.amd64.inputs += build/linux/x64/release/bundle
  mac.inputs += build/macos/Build/Products/Release/${pubspec.name}.app
}
  • Edit the four metadata lines at the start of the app object.

Create the unpackaged app

  • Create a self-contained directory and run the app from there:
conveyor run
  • Get the app into the output directory and take a look.
conveyor make app
conveyor make windows-app

One of the following for Intel/Apple Silicon Macs respectively:

conveyor -Kapp.machines=mac.amd64 make mac-app
conveyor -Kapp.machines=mac.aarch64 make mac-app
conveyor make linux-app

Restrict to your host machine

Conveyor can build packages for every OS from any OS, so normally we'd now compile our test app on Windows, macOS and Linux then get all the binaries onto the same machine. To save time for now we'll restrict Conveyor to building packages only for your current OS. Later we'll see how to use GitHub Actions as a source of binaries for each OS.

  • Inside the app { .. } block, add machines = windows.amd64
  • Inside the app { .. } block, add machines = mac
  • Inside the app { .. } block, add machines = linux.amd64.glibc

Tip

The conveyor.conf syntax is a superset of JSON designed for humans writing config files. You can write raw JSON if you're ever unsure about syntax. app.foo.bar = 123 is equivalent to app { foo { bar = 123 } }.

Serve the download site

A plain directory can't be installed or updated. Let's fix that by making self-updating packages.

conveyor make site
cd output
npx serve .

It's self-signed, so you'll need to follow the instructions for how to install it. We'll fix that later.

Serving localhost

Above we use npm and the JavaScript serve module as a simple localhost web server. You can use any web server that properly supports HTTP Content-Range requests. Some servers have bugs therefore we recommend using npx serve . even though this isn't a JavaScript project. You can also use Caddyserver by running caddy file-server --browse --listen :3000. In particular don't use the built in Python web server. It won't work correctly for Windows installs.

Release an update

In another terminal tab:

  • Edit pubspec.yaml and change the version field to 2.0.
  • Run the build command you used in the first step.
  • Run conveyor make site to regenerate the download site.

Run the program you installed in the previous step. You should see a window appear with a progress bar, the update be applied and the app should then start, all without any user interaction.

This happens because the sample conveyor.conf file is using the app.updates = aggressive key. Learn more about update modes.

Run the program you installed in the previous step. You should see a window appear with a progress bar, the update be applied and the app should then start, all without any user interaction.

This happens because the sample conveyor.conf file is using the app.updates = aggressive key. Learn more about update modes.

If on Debian derived distributions: Run apt-get update; apt-get upgrade to get the newest version of your app. Otherwise, there is no automatic update supported right now, sorry.

Change the icon

Conveyor can set the icons for your app on every platform given some image inputs, or even generate a synthetic icon for you.

  • Run conveyor make rendered-icons
  • Look in the output directory to find your new icons.

Basic, but functional.

  • Set the app.icons key to this:
    app {
      icons {
         label = XY
         gradient = blue
      }
    }
    
  • Rerun conveyor make rendered-icons and look at the results again.

The generated icons will be used automatically.

Tip

Icon generation is meant for quick prototypes, internal tools, student projects and other cases where it's just not worth drawing a pretty icon for your app.

Learn more about icons

Integrate with a continuous build

Compiling your app on every supported OS is annoying. Let's use GitHub Actions to compile our app for us. You can use any CI system of course, the procedure will be similar.

  • Upload your sample app to GitHub.
  • Delete the inputs section of your config and replace it with this:
    windows.amd64.inputs += artifacts/windows
    linux.amd64.inputs += artifacts/build-linux-amd64.tar
    mac.amd64.inputs += artifacts/build-macos-amd64.tar
    mac.aarch64.inputs += artifacts/build-macos-aarch64.tar
    
  • Add a build workflow file to .github/workflows and commit/push it. It should look like the build.yml file on this example.
  • Locate and copy the value of your root key.
  • Create a GitHub Encrypted Secret named SIGNING_KEY, and paste the value copied above (without the surrounding quotes).
  • Add a deploy workflow file to .github/workflows and commit/push it. It should look like the deploy-to-gh.yml file on this example.

Note

Learn more about using continuous integration

Upload a real update site

  • Set the app.license key to the name of your software license e.g. Apache 2, GPL-3 etc. Use SPDX codes if you aren't sure what to put here.
  • Upload your project source code to GitHub.
  • In your config set this key: app.vcs-url = "https://github.com/you/your-project". This automatically sets app.site.base-url to point at the latest GitHub Release.
  • Create a Fine Grained Personal Access Token with Read and Write access to your repository Contents.
  • Set the app.site.github.oauth-token key to the value of the token created above.
  • (optional) Set the app.site.github.pages-branch key to gh-pages.
  • Run conveyor make copied-site.

Your installs will update to whatever the latest release is.

You don't have to use GitHub. If you want to upload your site elsewhere make sure app.vcs-url is set to the URL of your source repository and set app.site.base-url to the URL where the generated site will be uploaded to.

When your app.site.base-url key is set to localhost or a domain that ends in .local Conveyor is in testing mode and you can use it for free. Once you set app.site.base-url to a real website you will be asked to pay and granted three license keys. Each key can be used with one site URL. If you want different update channels (e.g. beta, testing) then you'll need to different site URLs and one key for each.

  • Pick a site URL and set app.site.base-url to point to it, e.g. app { site.base-url = "https://downloads.example.com/myapp" }
  • Set the conveyor.billing-email key to the email address we can use to contact you for billing purposes.
  • Run conveyor make site.
  • You'll be asked to visit a payment URL where you can enter credit card data, and the conveyor.license-key key will be set to a short random code. This key is linked to your chosen download site URL.
  • Rerun conveyor make site.

To release an update you just re-upload the files to the site URL.

Learn more about download sites

Signing

Your users must follow annoying instructions to install the app. That's because it's being self-signed, not signed by a recognized certificate authority. Let's fix that.

When you ran your first command Conveyor announced it had generated a "root key" and that you should back it up. The root key is stored in your defaults.conf file and looks like this:

app.signing-key = "little peace follow cave drive pluck pony rebel grant barrel mammal skate devote skate amateur abandon shaft farm relax cousin few initial olive catch/2023-01-27T16:28:23Z"

Backups

  • Make a backup of your root key.

You must always back up your root key, even if you will later import signing keys you already have. The root key is also used for signing Mac update feeds, Linux packages and apt repositories.

It's represented as words so you can write it down with pen and paper for quick and safe offline backups. Remember to include the generation date!

All the different keys you need can be deterministically derived from this one root key.

The cheapest way to release your app to everyone is to join the Apple Developer Programme (about $100/yr) and then sign up for the Microsoft Store (about $19/yr for an individual, a bit more for companies). Conveyor can release via the Store and when you do this Microsoft will sign your software for you. This is cheaper and easier than buying signing certificates.

How to buy new certificates

A certificate request file (CSR) can be uploaded to a certificate authority like Apple, DigiCert or ssl.com to get back a certificate. The certificate links your public key to a verified personal or corporate identity and is included inside the app binaries on Windows and macOS along with the signatures. Conveyor generated two .csr files and printed the paths to them.

  • Log in using an Apple ID to the Apple developer programme. Joining will require a credit card payment.
  • Request a "Developer ID Application" certificate using the Apple Developer console. You can do this with any web browser and operating system, but you must be the account holder.
  • Upload the apple.csr file that was created next to your defaults.conf file when you created your root key above.

You'll get a .cer file back immediately. There is no review or approval process because the verification is linked to your credit card details.

  • Pick a certificate authority that sells Authenticode certificates. DigiCert is a good choice. Please refer to this FAQ section for more information on the difference between normal and EV certificates.
  • Upload the windows.csr file that was created next to your defaults.conf when you created a root key above. You will need to verify your identity with the CA.
  • Download the certificate in a format of your choice. Conveyor understands several but PEM works well.
  • Place your certificate files next to your defaults.conf. Name them apple.cer and windows.cer.
  • Add this to defaults.conf:
    app {
      mac.certificate = apple.cer
      windows.certificate = windows.cer
    }
    

If you're shipping to macOS you need to configure Apple notarization. Learn how to set up notarization.

  • Run conveyor make site or build unpackaged apps again. Your apps should now be signed and notarized.

Learn more about keys and certificates

Become a 🐢 tortoise

You will probably not be satisfied with the feature set shown in this short tutorial. The rest of the documentation awaits!