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.11-py3-none-win_amd64.whl (43.0 MB view details)

Uploaded Python 3Windows x86-64

bin_upload-0.0.11-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.11-py3-none-musllinux_1_2_aarch64.whl (38.2 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

bin_upload-0.0.11-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.11-py3-none-manylinux_2_17_aarch64.whl (40.5 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

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

Uploaded Python 3macOS 11.0+ ARM64

bin_upload-0.0.11-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.11-py3-none-win_amd64.whl.

File metadata

  • Download URL: bin_upload-0.0.11-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.11-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 d1ddb11ea6bfb37501cf48bd3f6b3a6ab93da81b3729c35f8bc8e9395246a52b
MD5 1b488a61a4331c9fe5b5e8ddc9cd6d0b
BLAKE2b-256 86500f60afec4e1b81d7e246ab534d806cb115dd0093704d2d7eb67c738f9a6c

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bin_upload-0.0.11-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.11-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 41a3f14508dcdcf323a0185cf98d8d0a376a5ce94a98a3bf0930cd1f876332ae
MD5 95894fffa1eb0c5a4ab4cb7148df605e
BLAKE2b-256 ca580df65dd8cc8bbf9cdae43a7de44c67131aea3e103902c11c0796a16df69e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bin_upload-0.0.11-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.11-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 b0eca07a6fb154ad17866b2afdc897acfb305fb14f38dca27bdc0d2decf6f468
MD5 42b3ee8ed70d2cc35b4cc8f1410b7a09
BLAKE2b-256 a6749f73b97421fcbad99fafa6fb02cecc6c81eda02a42fd198619c858dd2c10

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bin_upload-0.0.11-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.11-py3-none-manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 f3ffc8c5b916f60d1cf41bc2986a6b14f38723aa707ee6fef3ded39cc77ad0fd
MD5 019f408befdca49967954d675d1c7b31
BLAKE2b-256 65544a63d58b5cc1bc71450351855ba0f12371cb2c5e7cf736457969dc7eca8a

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bin_upload-0.0.11-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.11-py3-none-manylinux_2_17_aarch64.whl
Algorithm Hash digest
SHA256 461d29e1372ccde3a6d130f52a587b651da65cbf9ad88eb48de594c0db901ee3
MD5 ab8fa08f0fab174157ec33f227a5c4c5
BLAKE2b-256 83d127ca6594a82388c1ac918551b690a14b4b4c6c085f34b27d736226a624bb

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bin_upload-0.0.11-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.11-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f0990563d2ef2943eb0d5e800cfc0cc12e5637627d628a88942f3c4fdd20d9cf
MD5 e7ac1388e02242f281baf111691b84a3
BLAKE2b-256 5642fb851dd9ca513a2153d86df40cecb3041b2bacd85b52d81583c5592a92b2

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bin_upload-0.0.11-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.11-py3-none-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 bed97780e90794a1a721c0ae627448db4830addee9dc92afe09cb35f5637d73c
MD5 e021357a3e005ea09f28b3b26a6a744d
BLAKE2b-256 56f67ca8cc95d261899e1e2b3545fc5e8d99be6508ce369aede04e0218b72717

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