{"id":15567306,"url":"https://github.com/scolladon/sfdc-ci-toolkit","last_synced_at":"2025-10-18T00:29:45.524Z","repository":{"id":22366893,"uuid":"95989742","full_name":"scolladon/sfdc-ci-toolkit","owner":"scolladon","description":"CI Scripts for Salesforce projects","archived":false,"fork":false,"pushed_at":"2022-12-08T08:53:09.000Z","size":737,"stargazers_count":46,"open_issues_count":9,"forks_count":14,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-15T16:18:26.730Z","etag":null,"topics":["continuous-integration","sfdc"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/scolladon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-01T22:04:48.000Z","updated_at":"2024-03-09T07:27:59.000Z","dependencies_parsed_at":"2023-01-13T21:58:51.120Z","dependency_job_id":null,"html_url":"https://github.com/scolladon/sfdc-ci-toolkit","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scolladon%2Fsfdc-ci-toolkit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scolladon%2Fsfdc-ci-toolkit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scolladon%2Fsfdc-ci-toolkit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scolladon%2Fsfdc-ci-toolkit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scolladon","download_url":"https://codeload.github.com/scolladon/sfdc-ci-toolkit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249105474,"owners_count":21213537,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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-integration","sfdc"],"created_at":"2024-10-02T17:10:39.457Z","updated_at":"2025-10-18T00:29:40.481Z","avatar_url":"https://github.com/scolladon.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sfdc-ci-toolkit\nCI Scripts for Salesforce projects\n\nThis repository purpose is to centralized Continuous Integration scripts dedicated to the Salesforce platform.\nIt allows you to build your app, sanitized your repository (profile and permission sets) and automate things for you.\nIt has been designed and built to be fast, modular and to run with just npm as dependencies.\n\nYou can make it run into a basic alpine-node docker image.\nYou can easily add a tasks to this script for your own needs.\n\nCompatible and complementary to SalesforceDX\n\n\n## Getting Started\n\nWorks in Unix like system.\nWindows is not tested.\n\n### Installing\n\n```\n$ cd /your/sfdc/repo\n$ git clone https://github.com/scolladon/sfdc-ci-toolkit.git\n# Or :\n$ wget http://github.com/scolladon/sfdc-ci-toolkit/archive/master.zip\n$ unzip master.zip\n\n# Then :\n$ npm install\n```\nthen you can either remove .git folder or add it as a submodule of your sfdc repo\n\n### Tasks prepackaged\n\nSFDC-ci-toolkit comes with handy npm scripts for CI :\n```javascript\n\"scripts\": {\n  \"full-build\": \"npm run deploy\",\n  \"postfull-build\": \"npm run move-tag\",\n  \"predeploy\": \"gulp pre-deploy-script\",\n  \"deploy\": \"gulp deploy\",\n  \"postdeploy\": \"gulp post-deploy-script\",\n  \"partial-package\": \"gulp prepare-package\",\n  \"move-tag\": \"./movetag.sh\",\n  \"partial-build\": \"npm run partial-package\",\n  \"postpartial-build\": \"npm run deploy\",\n  \"coverage\": \"gulp coverage\",\n  \"profile-completion\": \"gulp profile-completion\",\n  \"profile-reconciliation\": \"gulp profile-reconciliation\",\n  \"generate-package\": \"gulp generate-package\",\n  \"generate-data-dictionary\": \"gulp generate-data-dictionary\",\n  \"display-coverage\": \"gulp read-coverage\",\n  \"prepare-runtests\": \"gulp prepare-runtests\",\n  \"retrieve\": \"gulp retrieve\",\n  \"dataload-insert\": \"gulp dataload-insert (--concurrencyMode \u003cSerial | Parallel\u003e)\",\n  \"dataload-update\": \"gulp dataload-update (--concurrencyMode \u003cSerial | Parallel\u003e)\",\n  \"dataload-upsert\": \"gulp dataload-upsert --extIdField \u003cmyExtIdFieldName\u003e (--concurrencyMode \u003cSerial | Parallel\u003e)\",\n  \"dataload-delete\": \"gulp dataload-delete (--concurrencyMode \u003cSerial | Parallel\u003e)\",\n  \"oneline-profile-and-ps\": \"gulp oneline-profile-and-ps\",\n  \"env-info\": \"gulp env-info\"\n}\n```\nCombined them smartly according to your need as a developer or as a release manager ;)\n\nHere is the list of scripts with their description available in the toolkit\n* **checkout-package** : Run it to check the file in the target branch from your package.xml. ex : gulp checkout-package --branch master\n* **coverage** : Run it just after having deployed with the RunLocalTests. It will gather the coverage and translate it to lcov format into coverage.json file\n* **deploy** : Run it to deploy your repo to Salesforce\n* **generate-package** : Run it to generate your package.xml from your repository\n* **generate-data-dictionary** : Run it to generate your data dictionary from your Salesforce org\n* **pre-deploy-script** : Run it to run execute anonymous each script files contained into PRE_SCRIPT_PATH variable\n* **post-deploy-script** : Run it to run execute anonymous each script files contained into POST_SCRIPT_PATH variable\n* **prepare-package** : Run it to generate package.xml and destructiveChanges.xml by diffing the HEAD commit and the commit sha into COMMIT variable\n* **prepare-runtests** : Run it to generate SF_RUNTESTS based on the src/classes folder and the SF_TESTSUFFIX variable\n* **profile-completion** : Run it to complete your non admin profiles \u0026 permission sets with the removed user permissions\n* **profile-reconciliation** : Run it to check the consistency of your repo and the profiles \u0026 permission sets definition into it\n* **display-coverage** : Run it after having deploy with test runned. It will display the code coverage\n* **prepare-runtests** : Run it to prepare the test classes to run for your specified test deployment\n* **retrieve** : Run it to retrieve package.xml from Salesforce to your repo\n* **dataload-insert** : Run it to insert data from csv file\n* **dataload-update** : Run it to update data from csv file\n* **dataload-upsert** : Run it to upsert data from csv file\n* **dataload-delete** : Run it to delete data from csv file\n* **oneline-profile-and-ps** : Run it to one line profiles and permission sets\n* **remove-user-permissions** : Run it to remove userPermissions in profiles and permission sets\n* **env-info** : Run it to check the current environment config used (if you have multiple .env files)\n\n## Usage Example\nLet's imagine you finalized the three first steps of [building a Conference Management app](https://trailhead.salesforce.com/en/projects/salesforce_developer_workshop/steps/creating_apex_class) in your sandbox and you want to deploy it to your dev org!\nFirst add the toolbox into your repo\n\n```\n$ cd /your/repo/path\n$ wget http://github.com/scolladon/sfdc-ci-toolkit/archive/master.zip\n$ unzip master.zip -d sfdc-ci-toolkit\n```\n\nadd sfdc-ci-toolkit to your gitignore and configure the toolbox (cf Configuration)\nThen you go to your repository and fetch the objects, the applications, the tabs, the classes and the profiles (field, tab and class access) metadata definition using your favorite ide\nThen you stage and commit your changes to the repo\n```\n$ git add src/objects/*\n$ git add src/applications/*\n$ git add src/tabss/*\n$ git add src/classes/EmailManager*\n$ git add src/profiles/*\n$ git commit -m 'Conference Management app thirs step cleared :rocket:'\n```\n\nthen you will probably complete your profile so your run the profile-completion task :\n```\n$ npm run profile-completion # Or if you have gulp globally installed: $ gulp profile-completion\n```\n\nthen you will probably check for inconsistency between your profile and the repository so your run the profile-reconciliation task :\n```\n$ npm run profile-reconciliation # Or if you have gulp globally installed: $ gulp profile-reconciliation\n```\n\nThen make your changes and staged everything into your repo\n```\n$ git add .\n$ git commit -m 'profile alignment'\n```\n\nThen you want to generate your package.xml.\nTwo way !\n* **Full** :\n```\n$ npm run generate-package # Or if you have gulp globally installed: $ gulp generate-package\n$ git add src/package.xml\n$ git commit -m 'package creation'\n```\n\n* **Incremental** : select the commit sha from which you want to compare and put it into a COMMIT variable into the .env file (you can use the CURRENT_BRANCH and COMPARE_BRANCH)\n```\n$ npm run partial-package # Or if you have gulp globally installed: $ gulp prepare-package\n$ git add src/package.xml src/destructive*\n$ git commit -m 'package creation'\n```\n\nThen you want to prepare the test to execute to allow you to have a lightning fast deployment using Specified Test.\nedit the SF_TESTSUFFIX variable int the .env file with your test suffix\n```\n$ npm run prepare-runtests # Or if you have gulp globally installed: $ gulp prepare-runtests\n```\nThen edit the SF_TESTLEVEL variable int the .env file with the value 'RunSpecifiedTests'\n\nNow you are ready to deploy !\nPackage your pre and post script into the folders configured into POST_SCRIPT_PATH and PRE_SCRIPT_PATH variables.\nExecute your pre deploy scripts\n```\n$ npm run predeploy # Or if you have gulp globally installed: $ gulp pre-deploy-script\n```\n\nYou are going to try the build before merging your dev. So, put the value 'true' into the SF_CHECKONLY variable into the .env file and :\n```\n$ gulp deploy\n```\n\nExecute your post deploy scripts\n```\n$ npm run postdeploy # Or if you have gulp globally installed: $ gulp post-deploy-script\n```\n\nIf you want to fetch the coverage from the deployment (works better with a RunLocalTests) execute this command :\n```\n$ npm run coverage # Or if you have gulp globally installed: $ gulp coverage\n```\nyou will get a the coverage to the lcov format in the file 'coverage.json' into the sfdc-ci-toolkit folder\n\nYou are ready to package your branch and merge it where you want (follow you development process) !\nAfter having merged the dev, you are ready to deploy. Change the SF_CHECKONLY to false.\nYou can launch a prepackaged script to automate those operations :\n* gulp gulp pre-deploy-script\n* gulp deploy\n* gulp gulp post-deploy-script\nby executing :\n```\n$ npm run deploy\n```\n\n## Configuration\ncopy the .env_sample file to a .env file in the root directory.\nIt contains the definition of each required parameters with aen example value.\nHere is what each line is used for and where:\n\nYou can optionnaly have multiple conf files.\nIn that case, initialize the SF_CONF_PATH env. variable with the path of the file you want to use.\n\n**SF_VERSION**\nUsed for: defining the Salesforce API version used\nType of value: float one decimal precision (ex: 39.0)\nUsed in:\n* deploy\n* generate-package\n* post-deploy-script\n* pre-deploy-script\n* post-deploy-script\n\n**SF_USERNAME**\nUsed for: connecting to Salesforce\nType of value: string email format\nUsed in:\n* deploy\n* post-deploy-script\n* pre-deploy-script\n\n**SF_PASSWORD**\nUsed for: connecting to Salesforce\nType of value: string\nUsed in:\n* deploy\n* post-deploy-script\n* pre-deploy-script\n\n**SF_SERVERURL**\nUsed for: connecting to Salesforce\nType of value: string url format\nUsed in:\n* deploy\n* post-deploy-script\n* pre-deploy-script\n\n\n**SF_TESTLEVEL**\nUsed for: defining the test strategy when deployinh\nType of value: string (NoTestRun | RunLocalTests | RunSpecifiedTests | RunAllTests)\nUsed in:\n* deploy\n\n**SF_RUNTESTS**\nUsed for: defining the test to run when SF_TESTLEVEL equals \"RunSpecifiedTests\"\nType of value: string apex test classes name\nUsed in:\n* deploy\n* prepare-runtests\n\n**SF_CHECKONLY**\nUsed for: defining the deployment mode\nType of value: boolean\nUsed in:\n* deploy\n* prepare-runtests\n* post-deploy-script\n* pre-deploy-script\n\n**SF_TESTSUFFIX**\nUsed for: selecting the test classes to run with the specified test\nType of value: string\nUsed in:\n* prepare-runtests\n\n**SF_SRC_PATH**\nUsed for: defining the path to the src folder\nType of value: string absolute or relative path from this folder\nUsed in:\n* deploy\n* generate-package\n* prepare-package\n* prepare-runtests\n* profile-completion\n* profile-reconciliation\n\n**SF_REPO_PATH**\nUsed for: defining the path to the repository folder (the folder which contains the .git and the src folders)\nType of value: string absolute or relative path from this folder\nUsed in:\n* prepare-package\n* post-deploy-script\n* pre-deploy-script\n\n**POST_SCRIPT_PATH**\nUsed for: defining the path to the post script folder (the folder which contains the post scripts to execute anonymous)\nType of value: string relative path from SF_REPO_PATH folder\nUsed in:\n* post-deploy-script\n\n**PRE_SCRIPT_PATH**\nUsed for: defining the path to the pre script folder (the folder which contains the pre scripts to execute anonymous)\nType of value: string relative path from SF_REPO_PATH folder\nUsed in:\n* pre-deploy-script\n\nHere is the list of optional parameters with their default value :\n* CURRENT_BRANCH : git branch name (string) of the current branch used in coverage prepare-package\n* COMPARE_BRANCH : git branch name (string) of the compare branch used in coverage prepare-package\n* CODECLIMATE_REPO_TOKEN : code climate repo token (string) used in coverage\n* COMMIT : git commit id (string) used in coverage prepare-package\n* SF_ALLOWMISSINGFILES : (boolean) used in deploy. Default: true\n* SF_IGNOREWARNINGS : (boolean) used in deploy. Default: true\n* SF_POLLINTERVAL : (integer) milliseconds used in deploy. Default: 5000*1000\n* SF_POLLTIMEOUT : (integer) seconds used in deploy. Default: 10*1000\n* SF_ROLLBACKONERROR : (boolean) used in deploy. Default: true\n* SF_SINGLEPACKAGE : (boolean) used in deploy. Default: true\n* SF_VERBOSE : (boolean) used in deploy. Default: true\n* SF_PROJECT : project name (string) used in data dictionary filename prefix\n* SF_CUSTOMOBJECTS : (boolean) used in data dictionary. Default: true\n\n## How to add/modify Task\n\nJust create a js file in the gulp-tasks folder following this canvas\n\n```javascript\n// Include whatever you need\n\nmodule.exports = (gulp plugins, options) =\u003e {\n  // use the options object (it contains all the paramters from .env file)\n  return cb =\u003e {\n    gulp.src('a glob pattern')\n    .pipe(plugins.yourPluginName())\n    .pipe(gulp.dest('/a/dest/path'));\n  };\n};\n```\n\n## Built With\n\n* [ansi-colors](https://github.com/doowb/ansi-colors) - Easily add ANSI colors to your text and symbols in the terminal. Used by webpack, gulp, and many others!\n* [decompress](https://github.com/kevva/decompress) - Extracting archives made easy\n* [envalid](https://github.com/af/envalid) - Environment variable validation for Node.js.\n* [fancy-log](https://github.com/gulpjs/fancy-log) - Log things, prefixed with a timestamp.\n* [gulp](https://github.com/gulpjs/gulp) - The streaming build system.\n* [gulp-jsforce-exec-anon](https://github.com/scolladon/gulp-jsforce-exec-anon) - Execute anonymous using JSforce.\n* [gulp-load-plugins](https://github.com/jackfranklin/gulp-load-plugins) - Automatically load in gulp plugins.\n* [gulp-rename](https://github.com/hparra/gulp-rename) - Rename files easily.\n* [gulp-zip](https://github.com/sindresorhus/gulp-zip) - ZIP compress files.\n* [minimist](https://github.com/substack/minimist) - parse argument options\n* [sfdc-authent-delegate](https://github.com/scolladon/sfdc-authent-delegate) - Authentication delegate for Salesforce.\n* [sfdc-generate-codeclimate-coverage](https://github.com/scolladon/sfdc-generate-codeclimate-coverage) - Code coverage converter to lcov from deployment result.\n* [sfdc-generate-data-dictionary](https://github.com/gavignon/sfdc-generate-data-dictionary) - Generate data dictionary from a Salesforce Org.\n* [sfdc-generate-package](https://github.com/scolladon/sfdc-generate-package) - generate package.xml from source.\n* [sfdc-git-package](https://github.com/scolladon/sfdc-git-package) - Create Package.xml and destructiveChangesPre.xml from git diff between two commits.\n* [sfdc-pps-completion](https://github.com/scolladon/sfdc-pps-completion) - Profile \u0026 Permission Set user permission completion.\n* [sfdc-pps-reconciliation](https://github.com/scolladon/sfdc-pps-reconciliation) - Display inconsistency between sources and profile \u0026 permission set.\n* [sfdc-specified-test](https://github.com/scolladon/sfdc-specified-test) - Salesforce specified test generation.\n* [xml2js](https://github.com/Leonidas-from-XIV/node-xml2js) - XML to JavaScript object converter.\n\n## Versioning\n\n[SemVer](http://semver.org/) is used for versioning.\n\n## Authors\n\n* **Sebastien Colladon** - *Initial work* - [scolladon](https://github.com/scolladon)\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscolladon%2Fsfdc-ci-toolkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscolladon%2Fsfdc-ci-toolkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscolladon%2Fsfdc-ci-toolkit/lists"}