Weld

Weld logo

Hex.pm VersionHexDocsGitHub

Weld is a graph-native publication system for Elixir monorepos.

It keeps the source repo as a normal multi-project workspace, builds a workspace graph, resolves one artifact boundary from a repo-local manifest, projects a standalone Mix package, verifies that generated package with normal Mix tooling, and prepares an archiveable release bundle for publication.

What It Does

Installation

Add weld to the root project that owns the repo's packaging and release flow.

def deps do
  [
    {:weld, "~> 0.7.1", runtime: false}
  ]
end

Release Lifecycle

The intended lifecycle is:

  1. run the normal source-repo checks
  2. run mix release.prepare
  3. optionally run mix release.track to update a durable projection
  4. run mix hex.publish from the prepared bundle when you are doing a release
  5. run mix release.archive

weld owns create, welded-package verification, prepared bundle creation, projection tracking, and archive preparation. Hex publish remains external.

mix weld.release.track is for tracked projected source, including unreleased or pre-release snapshots. It updates projection/<package_name> by default and creates that branch as an orphan on first use so the projection history stays isolated from the source repo history.

For coordinated pre-release validation across consumer repos, prefer normal version bumps to a prerelease Weld package such as 0.7.1-rc.1 rather than embedding repo-local path or git override logic in every consumer.

Example Manifest

Package-projection mode (default):

[
  workspace: [
    root: "../..",
    project_globs: ["core/*", "runtime/*"]
  ],
  dependencies: [
    external_lib: [
      requirement: "~> 1.2",
      opts: []
    ]
  ],
  artifacts: [
    my_bundle: [
      roots: ["runtime/local"],
      package: [
        name: "my_bundle",
        otp_app: :my_bundle,
        version: "0.1.0",
        description: "My welded package"
      ],
      output: [
        docs: ["README.md", "guides/architecture.md"]
      ],
      verify: [
        artifact_tests: ["packaging/weld/my_bundle/test"],
        hex_build: true,
        hex_publish: true,
        smoke: [
          enabled: true,
          entry_file: "packaging/weld/my_bundle/smoke.ex"
        ]
      ]
    ]
  ]
]

Monolith mode:

[
  workspace: [
    root: "../..",
    project_globs: ["core/*", "runtime/*"]
  ],
  artifacts: [
    my_monolith: [
      mode: :monolith,
      roots: ["runtime/api"],
      monolith_opts: [
        shared_test_configs: ["core/contracts"],
        test_support_projects: ["tooling/test_support"]
      ],
      package: [
        name: "my_monolith",
        otp_app: :my_monolith,
        version: "0.1.0",
        description: "My welded monolith"
      ],
      output: [
        docs: ["README.md"]
      ]
    ]
  ]
]

Core Commands

Standard-layout repos can omit the manifest path. weld now discovers, in order:

  1. build_support/weld.exs
  2. build_support/weld_contract.exs
  3. a single packaging/weld/*.exs
mix weld.inspect
mix weld.graph --format dot
mix weld.query deps runtime/local
mix weld.project
mix weld.verify
mix release.prepare
mix release.track
mix release.archive
mix weld.affected --task verify.all --base main --head HEAD

You can still pass an explicit manifest path when a repo carries more than one Weld manifest or when you want to target a nonstandard location.

Generated Output

Package-projection mode (default) projects under dist/hex/<package>/ using a component-preserving layout:

dist/
  hex/
    my_bundle/
      mix.exs
      projection.lock.json
      lib/
        my_bundle/
          application.ex
      components/
        core/contracts/
        runtime/local/
      test/

Monolith mode merges all selected packages into a single flat project under dist/monolith/<package>/:

dist/
  monolith/
    my_monolith/
      mix.exs
      projection.lock.json
      lib/
        my_monolith/
          application.ex
        fixture/
          store.ex
          api.ex
      test/
        core_store/
        runtime_api/
        support/
      config/
        config.exs
        sources/
        runtime_sources/
      priv/
        repo/migrations/

When selected projects expose OTP applications, weld synthesizes a merged lib/<otp_app>/application.ex that starts those children inside the welded package. In monolith mode this module also bootstraps per-package config at startup via Config.Reader.

When selected-package tests depend on non-selected workspace projects, declare those source-only support projects explicitly in monolith_opts[:test_support_projects]. weld copies that support code under test/support/weld_projects/ and fails closed if the discovered support set drifts from the manifest contract.

The welded artifact is a normal Mix project. weld.verify runs:

Package-projection mode:

You can opt out of the Hex-only steps per artifact with:

This is the correct setting for internal artifacts that intentionally depend on non-Hex git dependencies. When disabled, Weld records the step as :skipped instead of forcing a failing mix hex.build.

Monolith mode:

Monolith artifacts can also disable hex.build with verify: [hex_build: false] when they are intentionally not Hex-packagable.

Prepared release bundles include the projected project tree, release.json metadata, projection.lock.json, and an optional tarball when verify.hex_build is enabled. Bundle metadata remains portable across checkout locations because it records the manifest path relative to the repo root and the Weld version used to create the bundle.

Guides

License

This project is licensed under the MIT License. See LICENSE for details.