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. 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.
  • PyPI — Builds wheel (.whl) packages for each platform-specific tag. Tools such as pip and uv automatically install the correct wheel for the machine installing the package.
  • 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

  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.

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 .whl (wheel) files. Each wheel contains:

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

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.

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

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

Uploaded Python 3Windows x86-64

bin_upload-0.0.7-py3-none-musllinux_1_2_x86_64.whl (37.6 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

bin_upload-0.0.7-py3-none-musllinux_1_2_aarch64.whl (37.6 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

bin_upload-0.0.7-py3-none-manylinux_2_17_x86_64.whl (40.0 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

bin_upload-0.0.7-py3-none-manylinux_2_17_aarch64.whl (39.9 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

bin_upload-0.0.7-py3-none-macosx_11_0_arm64.whl (23.0 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

bin_upload-0.0.7-py3-none-macosx_10_9_x86_64.whl (24.9 MB view details)

Uploaded Python 3macOS 10.9+ x86-64

File details

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

File metadata

  • Download URL: bin_upload-0.0.7-py3-none-win_amd64.whl
  • Upload date:
  • Size: 42.4 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","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.7-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 ef28136e1947645ff7f9e79e0c04abdb460bf560d6adc9601f7bd94687c4d636
MD5 8a0b5dfaa9f65bef511b0c52384ed935
BLAKE2b-256 bbcd4d87a93ef73086ff88320654efb311c10e6bb7854d1323e7b66acad1b0d5

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bin_upload-0.0.7-py3-none-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 37.6 MB
  • Tags: Python 3, musllinux: musl 1.2+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","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.7-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 ae19bcc3c30cdee8417e9818be1db2e1efc7f1f87e15cdb50d0b244f922e76ef
MD5 bb743dde698ea70bd339c4ac0d3c0a0c
BLAKE2b-256 89dae3c2dc06a8582817ffde50617f11e064ab051f598b9b4d5e05edce3c3caf

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bin_upload-0.0.7-py3-none-musllinux_1_2_aarch64.whl
  • Upload date:
  • Size: 37.6 MB
  • Tags: Python 3, musllinux: musl 1.2+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","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.7-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 19b119089ee3f1cba79805260b9196bf0850ce7b5af837e3f430b8366d380cae
MD5 156618e70defb0bce8b40f0da5359a95
BLAKE2b-256 d705094f44b09d88d9651d80b12801db7e66c180139eab2ab2014c112043b5ae

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bin_upload-0.0.7-py3-none-manylinux_2_17_x86_64.whl
  • Upload date:
  • Size: 40.0 MB
  • Tags: Python 3, manylinux: glibc 2.17+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","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.7-py3-none-manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 29c167914be66149ffa163d28cc7210e574b809fa06c1c09c86ade0ff6614c07
MD5 5aa8f5a0775b0a85a2fa0359ef648e4f
BLAKE2b-256 d730485932524a34a4d2d4845209021b4138c66a5b19ad04e3b3c4cbe8b9b26f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bin_upload-0.0.7-py3-none-manylinux_2_17_aarch64.whl
  • Upload date:
  • Size: 39.9 MB
  • Tags: Python 3, manylinux: glibc 2.17+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","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.7-py3-none-manylinux_2_17_aarch64.whl
Algorithm Hash digest
SHA256 219a629a8177912cc767ff0fff43e87c4441cd1fe9244b61ddebf3c0ce405b29
MD5 6cddfb959a2ccbb28e6932d43f58bdf8
BLAKE2b-256 a31f203e9c1e8747a7c5a1c63578abf1bec8cc010150f054a318f0d55f744a5a

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bin_upload-0.0.7-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 23.0 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","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.7-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a031b7aa51c89a0d3430c78ef1cbee690fcf46742c88fa980f2dd8550a21c95d
MD5 ab97206e86cdbbf7ecc313f6b88ec432
BLAKE2b-256 184c5d5ff3d346c9417579de48e372e2fa10a7d95d17891d35f4280faab8aa55

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bin_upload-0.0.7-py3-none-macosx_10_9_x86_64.whl
  • Upload date:
  • Size: 24.9 MB
  • Tags: Python 3, macOS 10.9+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","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.7-py3-none-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 f77d99f2ace1586d9e559ce1c4d37cfaeffedae1c80b4991f8d7860702cbd0ce
MD5 dc0bdac076d703ba36d0f143c815effd
BLAKE2b-256 7b7ca5b9a636c06bd31f0cb4d3f4ccc56d778f07b265e078cd68c45b120a91c0

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