Skip to main content

Publish binaries to npm, pypi, and github releases.

Project description

Bin Upload

Easily distribute binaries via npm, pypi, and GitHub releases.

Overview

bin-upload is a CLI tool built with Bun that packages and publishes pre-built binaries to multiple registries and platforms. It supports:

  • npm — Publishes a main package that depend on platform-specific binary packages using optionalDependencies.
  • PyPI — Builds wheel (.whl) packages for each platform-specific tag.
  • GitHub Releases — Creates releases and uploads archive assets (.tar.gz or .zip).

Installation

From npm

# Globally
npm install -g @d-dev/bin-upload
# or as a package dep
npm install -D @d-dev/bin-upload
# or run with npx
npx @d-dev/bin-upload <command>

From PyPI

pip install bin-upload
# or with UV
uv tool install bin-upload
# or run with uvx
uvx bin-upload <command>

From GitHub Releases

Download the appropriate binary for your platform from the releases page.

Quick Start

Requirements

The following must be installed and available on your path.

  • npm: if publishing to npm
  • uv: if publishing to pypi
  1. Initialize a configuration file:

    bin-upload init
    

    This will walk you through an interactive prompt and generate a bin-upload.config.yaml file.

  2. Pack binaries into publishable artifacts:

    bin-upload pack
    

    This will generate artifacts that can be published to npm (tarballs), pypi (wheel), and GitHub (tarballs and zips).

  3. Publish the artifacts:

    bin-upload publish
    

    This publishes the artifacts generatd by the pack command.

Commands

init

Initialize a bin-upload configuration file via interactive prompts.

bin-upload init [options]
Option Description
--help, -h Show help.
--config, -c Path to output configuration file.
--force, -f Overwrite existing configuration file.

pack

Build publishable artifacts (npm tarballs, PyPI wheels, GitHub archives) from your binaries.

bin-upload pack [options]
Option Description
--help, -h Show help.
--config, -c Path to YAML configuration file. Default: bin-upload.config.yaml.
--set, -s Set configuration values, e.g., --set npm.packageJson.version=1.0.0.
--source Sources to pack: all, npm, pypi, github. Default: all.
--verbose Enable verbose logging.

publish

Publish the packed artifacts to their respective registries.

bin-upload publish [options]
Option Description
--help, -h Show help.
--config, -c Path to YAML configuration file. Default: bin-upload.config.yaml.
--set, -s Set configuration values, e.g., --set pypi.publish.token=some-token.
--source Sources to publish: all, npm, pypi, github. Default: all.
--verbose Enable verbose logging.

Configuration

The configuration file is a YAML file (default: bin-upload.config.yaml) that supports Eta templating with access to environment variables and built-in variables.

Template Variables

  • env — Access environment variables, e.g., <%= env.NPM_TOKEN %>.
  • vars.gitTag — The latest semver git tag (without the v prefix), extracted from tags matching v*.*.*.

Configuration Structure

binaries:
  # binaryId -> path to binary file
  linux-x64: "./bin/linux-x64/my-binary"
  darwin-arm64: "./bin/darwin-arm64/my-binary"
  win-x64: "./bin/win-x64/my-binary.exe"

pack:
  prePackCommand: "bun run build" # Optional command to run before packing
  dir: "./dist" # Output directory for packed artifacts

npm:
  readmeFile: "README.md"
  licenseFile: "LICENSE"
  packageJson:
    name: "@scope/my-package"
    version: <%= vars.gitTag %>
    description: "My binary package"
    license: "MIT"
  binaryPackages:
    # binaryId -> { name, os, arch } using Node.js process.platform/process.arch values
    linux-x64:
      name: "@scope/my-package-linux-x64"
      os: "linux"
      arch: "x64"
    darwin-arm64:
      name: "@scope/my-package-darwin-arm64"
      os: "darwin"
      arch: "arm64"
    win-x64:
      name: "@scope/my-package-win-x64"
      os: "win32"
      arch: "x64"
  binNames:
    - "my-binary" # Optional custom bin entry point names
  publish:
    access: "public"
    tag: "latest"
    # For publishing from local machine
    # Should omit if publishing from GitHub actions
    # using trusted publisher with npm
    "registry=https://registry.npmjs.org/": true
    "//registry.npmjs.org/:_authToken=<%= env.NPM_TOKEN %>": true

pypi:
  readmeFile: "README.md"
  platformTags:
    # binaryId -> wheel platform tag
    linux-x64: "manylinux_2_17_x86_64"
    darwin-arm64: "macosx_11_0_arm64"
    win-x64: "win_amd64"
  metadata:
    Name: "my-package"
    Version: <%= vars.gitTag %>
    Summary: "My binary package"
    Requires-Python: ">=3.11"
  entryPointNames:
    - "my-binary" # Optional custom console_scripts entry points
  publish:
    # For publishing from local machine
    # should omit if publishing from GitHub actions
    # using trusted publisher with pypi
    token: "<%= env.PYPI_TOKEN %>"

github:
  owner: "my-org"
  repo: "my-repo"
  # Token should have the following repository level permissions
  # Metadata read
  # Contents read and write
  token: "<%= env.GITHUB_TOKEN %>"
  release:
    tag_name: "v<%= vars.gitTag %>"
  archives:
    # Simple: binaryId -> format
    linux-x64: "tar.gz"
    win-x64: "zip"
    # Advanced: custom archive with file globs
    # source:
    #   format: "tar.gz"
    #   files:
    #     - cwd: "src"
    #       pattern: "**/*"
    #     - "README.md"

Setting Config Values via CLI

Use --set (-s) to override configuration values using dot notation:

bin-upload pack -s npm.packageJson.version=1.0.0 -s pypi.metadata.Version=1.0.0
bin-upload publish -s "pypi.publish.token=some-token"

This will create the following values in the yaml configuration.

npm
  packageJson
    version: 1.0.0

pypi
  metadata
    Version: 1.0.0

Escape dots and equals signs with backslashes when they are part of the key:

bin-upload publish -s "npm.publish.registry\=https://registry\.npmjs\.org/=true"

This will create the following values in the yaml configuration.

npm
  publish
    "registry=https://registry.npmjs.org/": true

How it Works

npm

The pack command generates:

  • A main package that detects the user's platform (process.platform + process.arch) and delegates to the appropriate binary package.
  • Platform-specific packages listed as optionalDependencies in the main package, each containing the binary for that platform.

Bin upload publishes a main npm package that depend on platform-specific binary packages using optionalDependencies. When the main package is installed, the corresponding platform-specific package containing the actual binary is also installed. This allows for downloading and installing only the necessary binary without relying on post-install scripts, which some package managers do not run for dependencies.

Note: musl Linux binaries cannot be distinguished from glibc Linux binaries via process.platform/process.arch, so they cannot be published to npm.

PyPI

The pack command builds platform-specific wheel (.whl) files. Each wheel contains:

  • A Python wrapper module that locates and executes the bundled binary.
  • Console script entry points for CLI usage.

Bin upload builds and published wheel (.whl) packages for each platform-specific tag. Only one PyPi package is created containing the platform-specific wheel files (unlike npm where each binary is published to its own npm package). Tools such as pip and uv automatically install the correct wheel for the machine installing the package.

GitHub Releases

The pack command creates .tar.gz or .zip archives. The publish command creates a GitHub release (if one doesn't exist for the tag) and uploads the archives as release assets.

Publishing

The npm cli is used to publish to npm while uv is used to publish to PyPi.

Environment Variables

Variable Used By
NPM_TOKEN npm publish authentication
PYPI_TOKEN PyPI publish authentication
GITHUB_TOKEN GitHub API authentication

These can be set in a .env file or your CI environment. When using trusted publishers (e.g., GitHub Actions OIDC), tokens may not be required.

Publishing

One of the variables available for reference in the configuration file is gitTag, a reference to the latest git tag on the current git branch that matches v\d+\.\d+\.\d+ (the variable is without the leading v). Referencing this variable in the configuration allows for git-based release process and bypasses the need to manually update version numbers when releasing.

Local git-based Release Flow

git add .
git commit -m "..."
git tag -a v1.0.0 -m "Release v1.0.0"
# The tag needs to exist in the remote
# in order for bin-upload to create a release
# for the tag and upload assets
git push --follow-tags
bin-upload pack
bin-upload publish

Publishing with GitHub actions

The following GitHub action will publish the binary artifacts whenever a version tag is pushed to the repo. You will need to establish trusted publishing between the GitHub repo and npm and/or pypi if publishing to those locations.

# .github/workflows/relesae.yml
name: Release

on:
  push:
    tags:
      - "v*"

permissions:
  contents: write
  id-token: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: "24"
          registry-url: "https://registry.npmjs.org"

      - name: Install uv
        uses: astral-sh/setup-uv@v7

      - name: Build binaries
        run: COMMAND TO BUILD YOUR BINARIES

      - name: Pack
        run: uvx bin-upload pack

      - name: Publish
        run: uvx bin-upload publish
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

With the above GitHub action, you no longer need to set auth or tokens in the npm.publish and pypi.publish sections. You still need to reference the GITHUB_TOKEN in the github portion of the config.

From here, the release process is similar to releasing from local machine

git add .
git commit -m "..."
git tag -a v1.0.0 -m "Release v1.0.0"
git push --follow-tags

Development

This project uses Bun as its runtime and build tool.

# Install dependencies
bun install

# Build binaries for all platforms
bun run build

# Build for a specific target
bun run ./scripts/build.ts bun-darwin-arm64

# Lint and format
bun run check
bun run fix

License

MIT — Copyright (c) Derek Worthen

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

bin_upload-0.0.12-py3-none-win_amd64.whl (43.0 MB view details)

Uploaded Python 3Windows x86-64

bin_upload-0.0.12-py3-none-musllinux_1_2_x86_64.whl (38.2 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

bin_upload-0.0.12-py3-none-musllinux_1_2_aarch64.whl (38.2 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

bin_upload-0.0.12-py3-none-manylinux_2_17_x86_64.whl (40.6 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

bin_upload-0.0.12-py3-none-manylinux_2_17_aarch64.whl (40.5 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

bin_upload-0.0.12-py3-none-macosx_11_0_arm64.whl (23.6 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

bin_upload-0.0.12-py3-none-macosx_10_9_x86_64.whl (25.5 MB view details)

Uploaded Python 3macOS 10.9+ x86-64

File details

Details for the file bin_upload-0.0.12-py3-none-win_amd64.whl.

File metadata

  • Download URL: bin_upload-0.0.12-py3-none-win_amd64.whl
  • Upload date:
  • Size: 43.0 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.5 {"installer":{"name":"uv","version":"0.10.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for bin_upload-0.0.12-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 2ec17ee71bf2664ffaa227637bac869f25f0d0fa970cde5e5e348bcbef1cc229
MD5 77223b291c265df17b1dc3a72f05b4d8
BLAKE2b-256 773fc09e41f28764eecf887d82e4c0147f2133800c3b4693293c7390a7dd274c

See more details on using hashes here.

File details

Details for the file bin_upload-0.0.12-py3-none-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: bin_upload-0.0.12-py3-none-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 38.2 MB
  • Tags: Python 3, musllinux: musl 1.2+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.5 {"installer":{"name":"uv","version":"0.10.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for bin_upload-0.0.12-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 0385d4cf7ce9ced8553918a0ed1355431ccd274173fbde095dc5b57a6938c0d2
MD5 8b28a00a2df151d44aab656b4997df16
BLAKE2b-256 712738b096ba37b46700ebaae6e2f0e7b3d8825b13eecd354e29f771c56be99e

See more details on using hashes here.

File details

Details for the file bin_upload-0.0.12-py3-none-musllinux_1_2_aarch64.whl.

File metadata

  • Download URL: bin_upload-0.0.12-py3-none-musllinux_1_2_aarch64.whl
  • Upload date:
  • Size: 38.2 MB
  • Tags: Python 3, musllinux: musl 1.2+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.5 {"installer":{"name":"uv","version":"0.10.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for bin_upload-0.0.12-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 1fa69d972522b9d834c50a547f7bb35e6fdef2bd786501c15e8e4b474f829f08
MD5 b543abe7b1868e397d1c9d211d1b9cad
BLAKE2b-256 c9ab97523e191ad978085398a87585768b9a1c7143c17633e0a1f2d11dd772cb

See more details on using hashes here.

File details

Details for the file bin_upload-0.0.12-py3-none-manylinux_2_17_x86_64.whl.

File metadata

  • Download URL: bin_upload-0.0.12-py3-none-manylinux_2_17_x86_64.whl
  • Upload date:
  • Size: 40.6 MB
  • Tags: Python 3, manylinux: glibc 2.17+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.5 {"installer":{"name":"uv","version":"0.10.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for bin_upload-0.0.12-py3-none-manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 8ae4f5b44606ac1c302b8b485caf091f1f557fb756f18a52394166425e91c8eb
MD5 c5d956625595ff9e345c6efdfb2e2865
BLAKE2b-256 9bae1d94ab446d0af2f4cfe40da901e5ae8244f3406c2af6a0d8a84f37b3139a

See more details on using hashes here.

File details

Details for the file bin_upload-0.0.12-py3-none-manylinux_2_17_aarch64.whl.

File metadata

  • Download URL: bin_upload-0.0.12-py3-none-manylinux_2_17_aarch64.whl
  • Upload date:
  • Size: 40.5 MB
  • Tags: Python 3, manylinux: glibc 2.17+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.5 {"installer":{"name":"uv","version":"0.10.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for bin_upload-0.0.12-py3-none-manylinux_2_17_aarch64.whl
Algorithm Hash digest
SHA256 1f7eb1134779721a48aceb6489befd3788abb84550c195151d8b8c6ca75f1888
MD5 a6911a8e008bd2dcc6163872e5825109
BLAKE2b-256 b6c7f61ca4e4ea551018873d24b9e4dc896c6bf8f2da5408f21709617f16cf25

See more details on using hashes here.

File details

Details for the file bin_upload-0.0.12-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: bin_upload-0.0.12-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 23.6 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.5 {"installer":{"name":"uv","version":"0.10.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for bin_upload-0.0.12-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e95416bff926bd06ae2ff1518603969df57988d671f14a0e27e668da201c61fb
MD5 7433d1eab6b0408527b9ccfcee4787d6
BLAKE2b-256 0c5f48dae63502e5b5d51d3d0a4b7227219efde484c77117b0a670ab9e1856e9

See more details on using hashes here.

File details

Details for the file bin_upload-0.0.12-py3-none-macosx_10_9_x86_64.whl.

File metadata

  • Download URL: bin_upload-0.0.12-py3-none-macosx_10_9_x86_64.whl
  • Upload date:
  • Size: 25.5 MB
  • Tags: Python 3, macOS 10.9+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.5 {"installer":{"name":"uv","version":"0.10.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for bin_upload-0.0.12-py3-none-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 ec81877115607390362dea1134a1e92bb0cb1afcc8cccf386803e9bbfc4be977
MD5 a9860f029f7260402b603ca8474f3241
BLAKE2b-256 bf36ec5fe306ad9b40e78e83b6971d49ce36e65853385f5786ed106884e523ae

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page