Skip to content

feat: official GitHub Action for shipping pkg binaries #248

@robertsLando

Description

@robertsLando

Packaging a Node.js app with pkg inside a GitHub Actions workflow today means hand-rolling the same pipeline over and over: install @yao-pkg/pkg, run it, locate the outputs, rename them, compress them, generate checksums, upload as artifacts or attach to a release. Every consumer reinvents this boilerplate and the results diverge (naming schemes, compression formats, checksum algorithms, cross-compile caveats, etc.).

Proposal

Ship a first-party yao-pkg/pkg-action repository that wraps the common pipeline. A minimal consumer should look like:

- uses: yao-pkg/pkg-action@v1
  with:
    config: .pkgrc.json
    targets: node22-linux-x64,node22-macos-arm64,node22-win-x64
    compress: tar.gz           # or zip, tar.xz, 7z, none
    filename: '{name}-{version}-{os}-{arch}'
    checksum: sha256
    attach-to-release: true

Inputs (initial scope)

Build configuration

  • config — path to pkg config (package.json, .pkgrc once feat: support a .pkgrc configuration file #238 lands, custom JSON/JS). Auto-detect by default.
  • entry — entry script if not specified in config.
  • targets — comma/newline-separated list. Defaults to host target.
  • modestandard or sea.
  • node-version — override the bundled Node.js major (e.g. 22, 24).
  • compress-node — pass-through for pkg's --compress (Brotli/GZip/None).
  • fallback-to-source — pass-through for the bytecode fallback flag (feat: add --fallback-to-source flag for bytecode failures #246).
  • public — expose source (--public).
  • extra-args — escape hatch for raw pkg CLI flags.

Post-build

  • compress — archive format: tar.gz | tar.xz | zip | 7z | none, one archive per target.
  • filename — output filename template. Tokens: {name}, {version}, {target}, {node}, {os}, {arch}, {sha} (short commit), {ref}, {date}, {tag}.
  • checksumsha256 | sha512 | md5 | none (or comma list). Emits sidecar *.sha256 files and a combined SHASUMS256.txt.
  • strip — strip debug symbols on Linux/macOS.

Signing & notarization

  • macos-sign-identity / macos-keychain-password — codesign wrapper.
  • macos-notarize + Apple ID / team ID / app-specific password — notarytool wrapper.
  • windows-sign-cert / windows-sign-password — signtool wrapper.

Publishing

  • upload-artifact — upload each produced file as a workflow artifact (default true).
  • artifact-name — artifact name template (defaults to filename).
  • attach-to-release — if the triggering ref is a tag, attach to the matching GitHub Release.
  • release-tag — override the target release tag.
  • draft-release / prerelease — pass-through to gh release.

Performance

  • cache — cache pkg-fetch Node.js downloads (default true).
  • cache-key — override the cache key.

Outputs

  • binaries — JSON array of produced binary paths (pre-compression).
  • artifacts — JSON array of final uploaded file paths (post-compression).
  • checksums — path to the combined SHASUMS*.txt.
  • version — resolved package version used in templating.

Stretch goals

  • Matrix helper — auto-expand targets into a job matrix so each platform runs on its native runner, dodging the cross-compile pitfalls tracked in NodeJS 22/24 issues/feedbacks tracker #87 / Cross-compilation from macOS to Linux on arm64 broken on >=22 #181.
  • Release notes block — render a markdown table of binaries + sizes + checksums and append it to the release body.
  • SBOM generation — emit CycloneDX/SPDX per binary.
  • SLSA / provenance — integrate with actions/attest-build-provenance.
  • Docker image — optionally wrap the Linux binary in a distroless image and push to GHCR.
  • Homebrew / Scoop manifests — generate and PR formula/manifest updates on release.
  • Step summary — markdown table with build time, binary size, compressed size, checksum per target.
  • Smoke-test hook — run a user-supplied script against each produced binary (ties into ci: add end-to-end integration workflow with zwave-js-ui #240).

Implementation notes

  • Prefer a composite action so setup-node + cache actions compose naturally; drop to a small JavaScript action only for pieces that need real logic (templating, checksums, archive creation, signing orchestration).
  • Keep the action repo separate from yao-pkg/pkg so it can version and release on its own cadence, but document the supported pkg major range.
  • Publish to the GitHub Marketplace once v1 stabilizes.
  • Seed examples/ with: single-binary release, multi-OS matrix, SEA mode, signed macOS bundle, attach-to-release.

Part of #235

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions