@moonbase.sh/cli
v0.1.1
Published
Publish product releases to Moonbase.sh from the command line or a CI job
Readme
@moonbase.sh/cli
Publish product releases to Moonbase from the command line or a CI job, in one command.
export MOONBASE_ENDPOINT=https://acme.moonbase.sh
export MOONBASE_API_KEY=mb_...
npx @moonbase.sh/cli release moon-terminal v1.4.0 "dist/Moon Terminal.dmg" "dist/Moon Terminal Setup.exe" --notes-file NOTES.md --publishThat uploads both files, creates release 1.4.0 of the product moon-terminal from them, and
publishes it. It needs Node.js 20 or later.
MOONBASE_ENDPOINT is your account's address and MOONBASE_API_KEY an API key. Both are under
Account settings > Developer in Moonbase. Every command also takes them as --endpoint and
--api-key, which win over the variables. Keep the key secret: in CI, put it in a secret rather
than in the workflow file. Prefer the variable to --api-key on a machine you share, since other
users can see a command's options while it runs, and your shell history keeps them.
Commands
release <product-id> <version> <file...>
Uploads the files and creates the release from them. Before it uploads anything, it checks that the
product exists, that the release does not (unless you pass --add) and that every file is there.
- The version is
MAJOR.MINOR.PATCH. A leadingvis dropped, so a Git tag likev1.4.0works as it is. - Each download is named after its file.
- A file's platform is guessed from its extension (
.dmgand.pkgare Mac,.exeand.msiWindows,.deb,.rpmand.AppImageLinux), then from a word in its name (mac,win,linux), and is Universal otherwise. Its architecture is guessed from a word in its name (arm64,x64,x86_64,universaland the like) and is left out otherwise. The command lists what it guessed before it uploads.--platformand--archset them for every file instead. - A file larger than 64 MiB is sent in parts, four at a time, and a part that fails is retried.
| Option | |
|---|---|
| --notes <text> | The release notes |
| --notes-file <path> | Read the release notes from a file |
| --platform <name> | Universal, Windows, Linux, Mac, iOS or Android |
| --arch <name> | Universal, X86, X64, Arm or Arm64 |
| --publish | Publish the release, so customers can download it. Without it the release stays unpublished. |
| --add | If the release exists, add the files to it. A file with the same name, platform and architecture as one already there replaces it. |
| --json | Print the release as JSON |
| --endpoint <url> | Your account's address, instead of MOONBASE_ENDPOINT |
| --api-key <key> | An API key, instead of MOONBASE_API_KEY |
publish <product-id> <version>
Publishes a release, so customers can download it. Takes --json, --endpoint and --api-key.
upload <file>
Uploads one file and prints its key, for adding it to a release through the API or
@moonbase.sh/api. Takes --endpoint and
--api-key.
Progress and messages go to stderr, so stdout holds only the key or, with --json, the release.
The exit code is 0 when the command worked, 1 when it failed and 2 when it was run the wrong way.
GitHub Actions
Release when a version tag is pushed:
on:
push:
tags: ['v*']
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./build.sh # puts the installers in dist/
- run: npx @moonbase.sh/cli release moon-terminal ${{ github.ref_name }} dist/* --publish
env:
MOONBASE_ENDPOINT: https://acme.moonbase.sh
MOONBASE_API_KEY: ${{ secrets.MOONBASE_API_KEY }}When each platform builds on its own runner, let each job add its files with --add, and publish
once they all have:
jobs:
build:
strategy:
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- run: ./build.sh
shell: bash
# bash, so `dist/*` is expanded on Windows too.
- run: npx @moonbase.sh/cli release moon-terminal ${{ github.ref_name }} dist/* --add
shell: bash
env:
MOONBASE_ENDPOINT: https://acme.moonbase.sh
MOONBASE_API_KEY: ${{ secrets.MOONBASE_API_KEY }}
publish:
needs: build
runs-on: ubuntu-latest
steps:
- run: npx @moonbase.sh/cli publish moon-terminal ${{ github.ref_name }}
env:
MOONBASE_ENDPOINT: https://acme.moonbase.sh
MOONBASE_API_KEY: ${{ secrets.MOONBASE_API_KEY }}Jobs that finish at the same moment are fine: when Moonbase turns one job's change away because another's landed first, the command sends it again. A rerun of a job replaces the files it added before, since they have the same names.
To keep a workflow on a version you have tried, pin it: npx @moonbase.sh/[email protected] release ....
