{"id":27239705,"url":"https://github.com/mcarvin8/sf-package-combiner","last_synced_at":"2026-06-06T04:00:41.838Z","repository":{"id":262021309,"uuid":"885146776","full_name":"mcarvin8/sf-package-combiner","owner":"mcarvin8","description":"Combine multiple Salesforce manifests (package.xml) into 1 file for deployments.","archived":false,"fork":false,"pushed_at":"2026-05-26T17:18:16.000Z","size":1667,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-26T19:25:06.829Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mcarvin8.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-11-08T03:26:24.000Z","updated_at":"2026-05-26T17:18:20.000Z","dependencies_parsed_at":"2024-11-10T00:25:46.977Z","dependency_job_id":"81a3214f-5214-4964-bf3f-fef63bf11650","html_url":"https://github.com/mcarvin8/sf-package-combiner","commit_stats":null,"previous_names":["mcarvin8/sf-package-combiner"],"tags_count":47,"template":false,"template_full_name":null,"purl":"pkg:github/mcarvin8/sf-package-combiner","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcarvin8%2Fsf-package-combiner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcarvin8%2Fsf-package-combiner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcarvin8%2Fsf-package-combiner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcarvin8%2Fsf-package-combiner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mcarvin8","download_url":"https://codeload.github.com/mcarvin8/sf-package-combiner/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcarvin8%2Fsf-package-combiner/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33692997,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["continuous-deployment","deployment","manifest","salesforce"],"created_at":"2025-04-10T19:13:41.485Z","updated_at":"2026-06-06T04:00:41.821Z","avatar_url":"https://github.com/mcarvin8.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sf-package-combiner\n\n[![NPM](https://img.shields.io/npm/v/sf-package-combiner.svg?label=sf-package-combiner)](https://www.npmjs.com/package/sf-package-combiner)\n[![Downloads/week](https://img.shields.io/npm/dw/sf-package-combiner.svg)](https://npmjs.org/package/sf-package-combiner)\n[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://raw.githubusercontent.com/mcarvin8/sf-package-combiner/refs/heads/main/LICENSE.md)\n[![Maintainability](https://qlty.sh/badges/c16e960e-68ce-4dc9-b0d1-47116b0b04da/maintainability.svg)](https://qlty.sh/gh/mcarvin8/projects/sf-package-combiner)\n[![codecov](https://codecov.io/gh/mcarvin8/sf-package-combiner/graph/badge.svg?token=7YH0L48X3E)](https://codecov.io/gh/mcarvin8/sf-package-combiner)\n[![Mutation testing badge](https://img.shields.io/endpoint?style=flat\u0026url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fmcarvin8%2Fsf-package-combiner%2Fmain)](https://dashboard.stryker-mutator.io/reports/github.com/mcarvin8/sf-package-combiner/main)\n\n`sf-package-combiner` merges multiple `package.xml` manifests into one. Use it in CI/CD pipelines to combine sfdx-git-delta output, manual lists, or other tool-generated manifests before a single `sf project deploy start`.\n\n\u003c!-- TABLE OF CONTENTS --\u003e\n\u003cdetails\u003e\n  \u003csummary\u003eTable of Contents\u003c/summary\u003e\n\n  - [Quick start](#quick-start)\n  - [Command reference](#command-reference)\n    - [`sf sfpc combine`](#sf-sfpc-combine)\n  - [How it works](#how-it-works)\n  - [Example](#example)\n  - [Invalid package.xml files](#invalid-packagexml-files)\n  - [Requirements](#requirements)\n  - [Issues](#issues)\n  - [License](#license)\n\u003c/details\u003e\n\n---\n\n## Quick start\n\n```bash\n# Install\nsf plugins install sf-package-combiner@latest\n\n# Combine 2 manifests into 1\nsf sfpc combine -f pack1.xml -f pack2.xml -c package.xml\n```\n\nMix files and directories: use `-f` for specific files, `-d` for directories containing `package.xml` files.\n\n---\n\n## Command reference\n\n### `sf sfpc combine`\n\nCombine Salesforce manifest files into one `package.xml`.\n\n```\nUSAGE\n  $ sf sfpc combine [-f \u003cvalue\u003e] [-d \u003cvalue\u003e] [-c \u003cvalue\u003e] [-v \u003cvalue\u003e] [-n] [--json]\n\nFLAGS\n  -f, --package-file=\u003cvalue\u003e     Path to a package.xml file. Can be repeated.\n  -d, --directory=\u003cvalue\u003e        Path to a directory containing package.xml files. Can be repeated.\n  -c, --combined-package=\u003cvalue\u003e Path for the output file. Default: package.xml\n  -v, --api-version=\u003cvalue\u003e      API version for the combined package (e.g. 62.0).\n  -n, --no-api-version           Omit the \u003cversion\u003e element in the output.\n\nGLOBAL FLAGS\n  --json  Output as JSON.\n```\n\n**Examples**\n\n```bash\n# Two files → package.xml (overwrites the input)\nsf sfpc combine -f package.xml -f pack2.xml -c package.xml\n\n# Files + directory\nsf sfpc combine -f pack1.xml -f pack2.xml -d \"test/sample_dir\" -c package.xml\n\n# Pin API version\nsf sfpc combine -f pack1.xml -f pack2.xml -v \"62.0\" -c package.xml\n\n# No version in output\nsf sfpc combine -f pack1.xml -f pack2.xml -n -c package.xml\n```\n\n---\n\n## How it works\n\n- **Metadata types** — `\u003cname\u003e` values are normalized via Salesforce's metadata registry (correct casing, deduped).\n- **Type order** — `CustomObject` is always listed before all other types; remaining types sort alphabetically. This avoids deployment failures when `CustomObject` and its children appear in the same manifest (see [scolladon/sfdx-git-delta#76](https://github.com/scolladon/sfdx-git-delta/pull/76)).\n- **Members** — `\u003cmembers\u003e` values keep their original case (Salesforce API names are case-sensitive).\n- **API version** — Highest `\u003cversion\u003e` from all input manifests is used. Override with `-v`, or omit entirely with `-n`.\n\n---\n\n## Example\n\n**Input: `package1.xml`**\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cPackage xmlns=\"http://soap.sforce.com/2006/04/metadata\"\u003e\n  \u003ctypes\u003e\n    \u003cmembers\u003eMyApexClass\u003c/members\u003e\n    \u003cname\u003eApexClass\u003c/name\u003e\n  \u003c/types\u003e\n  \u003cversion\u003e60.0\u003c/version\u003e\n\u003c/Package\u003e\n```\n\n**Input: `package2.xml`**\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cPackage xmlns=\"http://soap.sforce.com/2006/04/metadata\"\u003e\n  \u003ctypes\u003e\n    \u003cmembers\u003eMyTrigger\u003c/members\u003e\n    \u003cname\u003eApexTrigger\u003c/name\u003e\n  \u003c/types\u003e\n  \u003cversion\u003e62.0\u003c/version\u003e\n\u003c/Package\u003e\n```\n\n**Command**\n\n```bash\nsf sfpc combine -f \"package1.xml\" -f \"package2.xml\" -c \"package.xml\"\n```\n\n**Output: `package.xml`**\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cPackage xmlns=\"http://soap.sforce.com/2006/04/metadata\"\u003e\n  \u003ctypes\u003e\n    \u003cmembers\u003eMyApexClass\u003c/members\u003e\n    \u003cname\u003eApexClass\u003c/name\u003e\n  \u003c/types\u003e\n  \u003ctypes\u003e\n    \u003cmembers\u003eMyTrigger\u003c/members\u003e\n    \u003cname\u003eApexTrigger\u003c/name\u003e\n  \u003c/types\u003e\n  \u003cversion\u003e62.0\u003c/version\u003e\n\u003c/Package\u003e\n```\n\nHighest input version (`62.0`) is used.\n\n---\n\n## Invalid package.xml files\n\nFiles that don't match the expected manifest structure or have no `\u003ctypes\u003e` are skipped with a warning. The underlying error from `@salesforce/source-deploy-retrieve` (SDR) is appended:\n\n```\nWarning: Invalid or empty package.xml: .\\test\\samples\\invalid2.xml. [SDR] Missing metadata type definition in registry: CustomFields\n```\n\n\u003e **Note:** A missing metadata type definition can also occur if the metadata type is newer than the SDR version bundled with this plugin. Dependabot checks for SDR updates weekly and auto-merges updates when the metadata registry changes.\n\nIf every input is invalid or empty, the output will have no `\u003ctypes\u003e`. Guard against deploying an empty package:\n\n```bash\nsf sfpc combine -f \"package/package.xml\" -f \"package.xml\" -c \"package.xml\"\nif grep -q '\u003ctypes\u003e' ./package.xml; then\n  echo \"---- Deploying added and modified metadata ----\"\n  sf project deploy start -x package.xml\nelse\n  echo \"---- No changes to deploy ----\"\nfi\n```\n\n---\n\n## Requirements\n\n- [Salesforce `sf` CLI](https://developer.salesforce.com/tools/sf)\n- Node.js **20.x or later**\n\n---\n\n## Issues\n\nBugs or feature requests? Submit an [issue](https://github.com/mcarvin8/sf-package-combiner/issues).\n\n---\n\n## License\n\n[MIT](LICENSE.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcarvin8%2Fsf-package-combiner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmcarvin8%2Fsf-package-combiner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcarvin8%2Fsf-package-combiner/lists"}