Installation
If you only use the GitHub Action you do not have to install anything — the Action downloads and caches the binary for you.
Homebrew
Section titled “Homebrew”brew install jtprogru/tap/notiflowCovers macOS on Apple silicon and Intel, and Linux on x86_64 and arm64. Shell completions are installed with the formula.
crates.io
Section titled “crates.io”cargo install notiflowBuilds from source, so it works on any target Rust supports — including ones the release matrix does not ship. Needs Rust 1.85 or newer.
One-line install
Section titled “One-line install”curl -fsSL https://raw.githubusercontent.com/jtprogru/notiflow/main/scripts/install.sh | shThe script detects your platform, resolves the latest release, verifies the archive against
the release’s checksums.txt, and installs into /usr/local/bin. On a system without
glibc it picks the static musl build automatically.
curl -fsSL .../install.sh | sh -s -- --version v2.0.1 --bin-dir ~/.local/binPiping a script from the internet into a shell is exactly as much trust as it sounds like. Read it first, or use one of the other channels.
Release archive
Section titled “Release archive”Every release publishes a static binary per platform, plus checksums.txt and a cosign
bundle for each archive.
VERSION=v2.0.1TARGET=aarch64-apple-darwin # see the table belowBASE="https://github.com/jtprogru/notiflow/releases/download/${VERSION}"
curl -fsSLO "${BASE}/notiflow-${TARGET}.tar.gz"curl -fsSLO "${BASE}/checksums.txt"grep " notiflow-${TARGET}.tar.gz$" checksums.txt | shasum -a 256 -c -
tar -xzf "notiflow-${TARGET}.tar.gz"sudo install -m 0755 notiflow /usr/local/bin/notiflow| Platform | Target |
|---|---|
| Linux x86_64 (glibc) | x86_64-unknown-linux-gnu |
| Linux arm64 (glibc) | aarch64-unknown-linux-gnu |
| Linux x86_64 (static) | x86_64-unknown-linux-musl |
| Linux arm64 (static) | aarch64-unknown-linux-musl |
| macOS Apple silicon | aarch64-apple-darwin |
| macOS Intel | x86_64-apple-darwin |
| Windows x86_64 | x86_64-pc-windows-msvc |
The musl builds are fully static, which is what you want inside an alpine or scratch
container.
Verifying the signature
Section titled “Verifying the signature”The checksum comes from the same server as the archive, so on its own it only proves the download was not corrupted. To prove the archive is the one the release workflow built:
cosign verify-blob "notiflow-${TARGET}.tar.gz" \ --bundle "notiflow-${TARGET}.tar.gz.bundle" \ --certificate-identity-regexp '^https://github.com/jtprogru/notiflow/\.github/workflows/release\.yml@refs/tags/' \ --certificate-oidc-issuer 'https://token.actions.githubusercontent.com'Releases also carry build provenance attestations:
gh attestation verify "notiflow-${TARGET}.tar.gz" --repo jtprogru/notiflowReleases from v2.0.0 onward also carry detached GPG signatures (.asc files next to each
artefact), made with the maintainer’s key:
pub ed25519 2025-04-14 [SC] [expires: 2035-04-12] 6FE5 73A7 0EEF 276F CAB6 9C64 13B9 59D0 0CED AC9Duid Mikhail Savin (jtprogru) <jtprogru@gmail.com>Import it, then verify:
curl -fsSL https://jtprogru.github.io/notiflow/notiflow-signing-key.asc | gpg --importcurl -fsSLO "${BASE}/notiflow-${TARGET}.tar.gz.asc"gpg --verify "notiflow-${TARGET}.tar.gz.asc" "notiflow-${TARGET}.tar.gz"The same key is on keys.openpgp.org, which is the copy to prefer — it is not served by
the project:
gpg --keyserver hkps://keys.openpgp.org --recv-keys 6FE573A70EEF276FCAB69C6413B959D00CEDAC9DEither way, check the fingerprint against the one above. Fetching a key over the same channel as the thing it signs is a convenience, not a proof; the fingerprint is what you compare against a copy you got some other way.
The 2.0.0-alpha.1 and 2.0.0-alpha.2 pre-releases predate the signing key and have no
.asc files. cosign and the attestation cover every release, including those two.
Shell completions
Section titled “Shell completions”notiflow completions bash > /etc/bash_completion.d/notiflownotiflow completions zsh > "${fpath[1]}/_notiflow"notiflow completions fish > ~/.config/fish/completions/notiflow.fishpowershell and elvish are supported too.
Inside the Action
Section titled “Inside the Action”The Action resolves a version, downloads the matching archive, verifies its sha256 and caches it in the runner tool cache. To also require a cosign signature check, install cosign first and turn the input on:
- uses: sigstore/cosign-installer@v3- uses: jtprogru/notiflow@v2 with: verify_signature: true # ...Which version the Action installs
Section titled “Which version the Action installs”In order of precedence:
- the
versioninput, when set; - the
VERSIONfile in the checked-out Action tree — stamped at release time, so@v2,@v2.1.0and@<sha>all resolve deterministically; GITHUB_ACTION_REF, when it looks like a semver tag;- the newest release, resolved over the network, with a warning.
Only the last one can give two runs of the same pinned workflow different answers, which is why it warns.