{"id":108,"date":"2018-03-26T14:07:43","date_gmt":"2018-03-26T12:07:43","guid":{"rendered":"https:\/\/transferttexei.wordpress.com\/2021\/08\/10\/our-move-to-salesforce-dx-and-developer-controlled-packages\/"},"modified":"2023-08-16T15:21:35","modified_gmt":"2023-08-16T13:21:35","slug":"our-move-to-salesforce-dx-and-developer-controlled-packages","status":"publish","type":"post","link":"https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/","title":{"rendered":"Our move to Salesforce DX and Developer-Controlled Packages"},"content":{"rendered":"\r\n<p>Since the Spring \u201918, Second-Generation Packages can be installed in Production orgs. Three days after the release went out, we had our first DCP installed in Production. I\u2019m very excited about this new tool, and thought it could be interesting to share our journey with it.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">What is a Developer-Controlled Package\u00a0?<\/h2>\r\n\r\n\r\n\r\n<p>Except if you\u2019ve been meditating in a cave for the last two years, you should have heard of Salesforce DX.<\/p>\r\n<p>DX is standing for Developer Experience, bringing to Salesforce Developers a better and modern development flow.<\/p>\r\n<p>&nbsp;<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img fetchpriority=\"high\" decoding=\"async\" class=\"alignnone wp-image-2160\" src=\"https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_0S2bJ1xkAooffrQ3dcEqmQ.png\" alt=\"Illustration : Apllication Lifecycle Management\" width=\"799\" height=\"496\" srcset=\"https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_0S2bJ1xkAooffrQ3dcEqmQ-200x124.png 200w, https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_0S2bJ1xkAooffrQ3dcEqmQ-300x186.png 300w, https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_0S2bJ1xkAooffrQ3dcEqmQ-400x248.png 400w, https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_0S2bJ1xkAooffrQ3dcEqmQ-600x372.png 600w, https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_0S2bJ1xkAooffrQ3dcEqmQ-768x477.png 768w, https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_0S2bJ1xkAooffrQ3dcEqmQ.png 799w\" sizes=\"(max-width: 799px) 100vw, 799px\" \/><\/figure>\r\n\r\n\r\n\r\n<p>&nbsp;<\/p>\r\n<p>From planning to releasing, DX is bringing you better tooling, and as deployment has always been a challenging part of Salesforce development. I was very curious and excited about the new features coming with <a href=\"https:\/\/developer.salesforce.com\/docs\/atlas.en-us.sfdx_dev.meta\/sfdx_dev\/sfdx_dev_dev2gp.htm\" target=\"_blank\" rel=\"noopener\">Second-Generation Packaging<\/a>.<\/p>\r\n\r\n\r\n\r\n<p>Until now, we\u2019ve been using ant through the Force.com Migration Tool, and from time to time Change Sets. I personally mostly never used managed or unmanaged package. The first thing to notice when looking at the new packaging options is that there are 2 package types :<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li><a href=\"https:\/\/developer.salesforce.com\/docs\/atlas.en-us.sfdx_dev.meta\/sfdx_dev\/sfdx_dev_dev2gp_plan_pkg_types_managed.htm\" target=\"_blank\" rel=\"noopener\">Managed Packages<\/a><\/li>\r\n<li><a href=\"https:\/\/developer.salesforce.com\/docs\/atlas.en-us.sfdx_dev.meta\/sfdx_dev\/sfdx_dev_dev2gp_plan_pkg_types_locked_unlocked.htm\" target=\"_blank\" rel=\"noopener\">Developer Controlled Packages<\/a>.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p>Managed Packages are mostly used by ISVs, so we didn\u2019t go down that road.<\/p>\r\n\r\n\r\n\r\n<p>Developer Controlled Packages on the other hands, seems to be the perfect fit for Enterprise Customers that want to replace their Change Set\/Ant tooling with a more robust solution. Looking deeper, DCPs comes in 2 flavors :<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Locked<\/li>\r\n<li>Unlocked<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p>So what\u2019s the difference\u00a0? Once installed, a Locked DCP won\u2019t let you change the metadata, while Unlocked will just \u201cflag\u201d the metadata as being part of a Package, which content (code, fields, layouts\u2026) will remain editable.<\/p>\r\n\r\n\r\n\r\n<p>This will be interesting when trying to sort your \u201chappy soup\u201d of metadata, as explained in Dreamforce session <a href=\"https:\/\/www.youtube.com\/watch?v=Prlurg2ORnU&amp;t=1s\" target=\"_blank\" rel=\"noopener\">How Everyone Can Leverage Salesforce DX Packaging<\/a>.<\/p>\r\n\r\n\r\n\r\n<p>We choose to use Unlocked DCP, because at the time of writing Locked DCPs are still in Pilot and can only be installed in Scratch Orgs and Sandboxes.<\/p>\r\n<p>Moreover, having a Unlocked DCP installed means that we can still update our metadata, which seems a good backup plan in case we encounter any issue.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Selecting a\u00a0project<\/h2>\r\n\r\n\r\n\r\n<p>Our goal is to move our entire codebase to Salesforce DX. We did some extended testing of DX using Git and Scratch Orgs. And when DCPs come out we felt like this was the opportunity to move to the next level : put our work in Production using the DX development model from end to end.<\/p>\r\n\r\n\r\n\r\n<p>We had just started to work on an internal tool for the project team, which we quickly built on the Lightning Platform. This was the perfect project because :<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>It was a brand new project (no package to build from existing metadata)<\/li>\r\n<li>It had no dependency at all with the existing projects on the org<\/li>\r\n<li>We (the project team) were the end users of this tool, so even if we broke something only us were impacted<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p>Now we had chosen a project, we were ready to start our journey to DX and DCPs\u00a0!<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Creating a\u00a0Package2<\/h2>\r\n\r\n\r\n\r\n<p>Using DX from the start was easier, as <a href=\"https:\/\/developer.salesforce.com\/blogs\/2018\/02\/announcing-unlocked-packages-beta.html\" target=\"_blank\" rel=\"noopener\">any metadata type currently supported by Salesforce DX can be in an unlocked package<\/a>.<\/p>\r\n<p>So we didn\u2019t had to check the <a href=\"https:\/\/developer.salesforce.com\/docs\/atlas.en-us.sfdx_dev.meta\/sfdx_dev\/sfdx_dev_dev2gp_plan_component_types.htm\" target=\"_blank\" rel=\"noopener\">list of supported component types for Second-Generation Packages<\/a> (though you can have a look, DCP already includes almost everything).<\/p>\r\n\r\n\r\n\r\n<p>After a few days of development, we had a clean repo with all the metadata ready to be packaged. And that\u2019s a big change between Change Set\/Ant and DCPs :<\/p>\r\n<p>You don\u2019t start with an org from which you create\/retrieve your package. You create it directly from your source code in your repo !<\/p>\r\n\r\n\r\n\r\n<p>The first thing to do is create a Package2. You\u2019ll need to have enabled your <a href=\"https:\/\/developer.salesforce.com\/docs\/atlas.en-us.sfdx_setup.meta\/sfdx_setup\/sfdx_setup_enable_devhub.htm\" target=\"_blank\" rel=\"noopener\">DevHub<\/a> and <a href=\"https:\/\/developer.salesforce.com\/docs\/atlas.en-us.sfdx_setup.meta\/sfdx_setup\/sfdx_setup_enable_secondgen_pkg.htm\" target=\"_blank\" rel=\"noopener\">Second-Generation Packaging<\/a>, and logged in through the <a href=\"https:\/\/developer.salesforce.com\/tools\/sfdxcli\" target=\"_blank\" rel=\"noopener\">CLI<\/a>.<\/p>\r\n<p>If you\u2019re not familiar with Salesforce DX, the related <a href=\"https:\/\/trailhead.salesforce.com\/en\/trails\/sfdx_get_started\" target=\"_blank\" rel=\"noopener\">Trailhead trail<\/a> is a very good start.<\/p>\r\n\r\n\r\n\r\n<h4>To create a Package2, just run the following line :<\/h4>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n<blockquote>\r\n<pre>sfdx force:package2:create -n MyPackage -o Unlocked<\/pre>\r\n<\/blockquote>\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n\r\n\r\n\r\n<h4>This will give you a package id (starting with 0Ho) that you\u2019ll need to add to your sfdx-project.json file :<\/h4>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n<blockquote>\r\n<pre>{<\/pre>\r\n<pre>    \u201cpath\u201d: \u201cforce-app\u201d,<\/pre>\r\n<pre>    \u201cdefault\u201d: true,<\/pre>\r\n<pre>   <strong> \u201cid\u201d: \u201c0Ho\u2026\u201d,<\/strong><\/pre>\r\n<pre><strong>    \u201cversionName\u201d: \u201cv 1.0\u201d,<\/strong><\/pre>\r\n<pre><strong>    \u201cversionDescription\u201d: \u201cv1.0\u201d,<\/strong><\/pre>\r\n<pre><strong>    \u201cversionNumber\u201d: \u201c1.0.0.NEXT\"<\/strong><\/pre>\r\n<pre>}<\/pre>\r\n<\/blockquote>\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n\r\n\r\n\r\n<p>Note the versionNumber attribute. Each time you\u2019ll create a new version of your package, the NEXT keyword will automatically increment the build number to the next available for the package. This is pretty convenient.<\/p>\r\n\r\n\r\n\r\n<p>Now that your Package2 is created, let\u2019s create a Package2 Version from your code\u00a0!<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Creating a Package2\u00a0Version<\/h2>\r\n\r\n\r\n\r\n<h4>Just run the following line :<\/h4>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n<blockquote>\r\n<pre>sfdx force:package2:version:create -i 0Ho\u2026 -d force-app -k mySuperSecretKey<\/pre>\r\n<\/blockquote>\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n\r\n\r\n\r\n<h4>Your Package2 Version will be enqueued for creation, and then you\u2019ll be able to run another command to get the status (don\u2019t worry, you\u2019ll get this command line as an output of the previous one, so you\u2019ll just have to copy paste, you lazy developer :P) :<\/h4>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n<blockquote>\r\n<pre>sfdx force:package2:version:get -i 05i\u2026<\/pre>\r\n<\/blockquote>\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n\r\n\r\n\r\n<p>Let\u2019s stop for a second and add a few notes on what we\u2019ve done.<\/p>\r\n\r\n\r\n\r\n<p>I\u2019ve been using the short version of the flags on the command line, because it\u2019s faster to write.<\/p>\r\n<h4>Then I\u2019m used to them, but I could have written the same command with more explicit flag names :<\/h4>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n<blockquote>\r\n<pre>sfdx force:package2:version:create --package2id 0Ho\u2026 --directory force-app --installationkey mySuperSecretKey<\/pre>\r\n<\/blockquote>\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n\r\n\r\n\r\n<h4>You can get help on all CLI commands using -h on them, so running the following will get you all the flags you can use, both in their short and long version :<\/h4>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n<blockquote>\r\n<pre>sfdx force:package2:version:create -h<\/pre>\r\n<\/blockquote>\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n\r\n\r\n\r\n<p>package2id and directory should have the same values as the ones you\u2019ve added to your sfdx-project.json file under \u201cid\u201d and \u201cpath\u201d.<\/p>\r\n\r\n\r\n\r\n<p>All the source code that you have under this path will be used to create the DCP. That\u2019s right, coming from your local code, not from an org\u00a0!<\/p>\r\n<p>Another cool stuff : You won\u2019t have to write a package.xml manifest. Second-Generation Packaging is clever enough to understand what metadata is in the folder (finally!).<\/p>\r\n\r\n\r\n\r\n<p>One last thing to note is the installation key. What\u2019s that\u00a0?<\/p>\r\n<p>Well, something that wasn\u2019t obvious for me when I started playing with DCPs is that they are public. That\u2019s right. Well, you need to know the package id to install it, but still.<\/p>\r\n\r\n\r\n\r\n<p>That may be obvious for you if you\u2019ve been using managed\/unmanaged packages before, but when I started using DCP I was thinking something like DCP=Change Set\/Force.com Migration Tool V2.<\/p>\r\n\r\n\r\n\r\n<p>Your Change Sets can only be installed in the Production org from which the Sandbox was created, and your ant packages are usually stored locally.<\/p>\r\n\r\n\r\n\r\n<p>DCPs are like managed\/unmanaged packages. You can install them via an url (more about this in a second). So you\u2019ll really want to set an installation key if it\u2019s not a open source project.<\/p>\r\n\r\n\r\n\r\n<p>Hopefully you\u2019ll set a more secure installation key in your packages. :)<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Installing a Package 2\u00a0Version<\/h2>\r\n\r\n\r\n\r\n<h4>The first way to install a Package2 Version is to simply use an url, like you would do for any existing package :<\/h4>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n<blockquote>\r\n<pre>https:\/\/login.salesforce.com\/packaging\/installPackage.apexp?p0=04t\u2026<\/pre>\r\n<\/blockquote>\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n\r\n\r\n\r\n<h4>In case you forget the url format, it\u2019s also available through the command line if you list your packages :<\/h4>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n<blockquote>\r\n<pre>sfdx force:package2:version:list<\/pre>\r\n<\/blockquote>\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n\r\n\r\n\r\n<h4>The other option, that you\u2019ll want to use if you automate your deployments, is to install them through a CLI command :<\/h4>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n<blockquote>\r\n<pre>sfdx force:package:install -i 04t\u2026<\/pre>\r\n<\/blockquote>\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n\r\n\r\n\r\n<p>Note that this command is using the \u201cpackage\u201d keyword and not \u201cpackage2\u201d : the install process is the same for all types of packages.<\/p>\r\n\r\n\r\n\r\n<h4>Same as for package2 creation, you\u2019ll be able to query the status of the installation :<\/h4>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n<blockquote>\r\n<pre>sfdx force:package:install:get -i 04t\u2026<\/pre>\r\n<\/blockquote>\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n\r\n\r\n\r\n<p>That\u2019s it\u2026for installing a package in Scratch Org or Sandbox\u00a0!<\/p>\r\n\r\n\r\n\r\n<p>Production require one additional step.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Installing a DCP in Production<\/h2>\r\n\r\n\r\n\r\n<p>Once you\u2019ve written your code, created Package2 Versions, tested everything at that you\u2019re ready to go to Production, you\u2019ll need to update the version to set it as released.<\/p>\r\n\r\n\r\n\r\n<p>The thing is that in a development lifecycle, you\u2019ll likely create several (hundreds\u00a0?) of Package 2 Versions before being ready to go to Production. Once you\u2019re there, you don\u2019t want to install one of your beta package by mistake.<\/p>\r\n\r\n\r\n\r\n<h4>Setting a package as released is an easy step :<\/h4>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n<blockquote>\r\n<pre>sfdx force:package2:version:update -i 05i... -s<\/pre>\r\n<\/blockquote>\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n\r\n\r\n\r\n<p>Note that this time you\u2019ll need the Package2 Id starting by 05i (when you create your package version you\u2019ll get 2 Ids, a Package 2 Version Id (starting by 05i) and a Subscriber Package 2 Version Id (starting by 04t)).<\/p>\r\n<p>Don\u2019t worry, you can get all the Ids doing sfdx force:package2:version:list, and every time you\u2019ll do a -h on a command you\u2019ll be told which Id to use.<\/p>\r\n\r\n\r\n\r\n<p>Once your Package2 Version is set as released, you\u2019ll be able to deploy in Production, and voila\u00a0!<\/p>\r\n\r\n\r\n\r\n<p>One last thing you\u2019ll need to do is update you sfdx-project.json file. You can only have one released package per version number (1.0, 1.1\u2026).<\/p>\r\n<h4>So just increase the minor version number by one :<\/h4>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n<blockquote>\r\n<pre>{<\/pre>\r\n<pre>\u201cpath\u201d: \u201cforce-app\u201d,<\/pre>\r\n<pre>\u201cdefault\u201d: true,<\/pre>\r\n<pre>\u201cid\u201d: \u201c0Ho\u2026\u201d,<\/pre>\r\n<pre>\u201cversionName\u201d: \u201cv 1.<strong>1<\/strong>\u201d,<\/pre>\r\n<pre>\u201cversionDescription\u201d: \u201cv1.<strong>1<\/strong>\u201d,<\/pre>\r\n<pre>\u201cversionNumber\u201d: \u201c1.<strong>1<\/strong>.0.NEXT\"<\/pre>\r\n<pre>}<\/pre>\r\n<\/blockquote>\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Using Second-Generation Packages in an ALM\u00a0process<\/h2>\r\n\r\n\r\n\r\n<p>After creating and deploying our first versions manually using the command line, we then integrated it in our ALM process.<\/p>\r\n\r\n\r\n\r\n<p>A few tips related to this :<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Unlike metadata deployments, test are not run on package installation, run them (using force:apex:test:run)<\/li>\r\n<li>Don\u2019t use short flag names, using long ones will make it easier to understand for someone else<\/li>\r\n<li>Remove prompts for command lines that ask for confirmation. For instance, use the \u201cnoprompt\u201d flag when you release a Package2Version<\/li>\r\n<li>Use additional flags so that you don\u2019t have to poll to get the status of your package (\u201cwait\u201d for force:package2:version:create, \u201cwait\u201d and \u201cpublishwait\u201d for force:install:package)<\/li>\r\n<li>All commands can make use of a \u201cjson\u201d parameter, nifty to parse the result in your ALM tool<\/li>\r\n<li>Once created, there isn\u2019t an easy to see your package content. Use the \u201ctag\u201d flag to trace the build number linked to your Package2<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p>This will give you commands like this for package creation<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n<blockquote>\r\n<pre>sfdx force:package2:version:create --directory force-app --package2id 0Ho\u2026 --tag 42 --installationkey mySuperSecretKey --wait 30 --json<\/pre>\r\n<\/blockquote>\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n\r\n\r\n\r\n<p>and installation<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n<blockquote>\r\n<pre>sfdx force:package:install --id 04t --installationkey mySuperSecretKey --targetusername myOrg --publishwait 30 --wait 30<\/pre>\r\n<\/blockquote>\r\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Development Flow<\/h2>\r\n\r\n\r\n\r\n<p>At the end, we now have a pretty smooth development flow where every developer code \u201clocally\u201d on a Scratch Org, push and merge to the repo when they\u2019re ready.<\/p>\r\n<p>Then the ALM process takes care of everything for us :<\/p>\r\n<p>&nbsp;<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" class=\"aligncenter wp-image-2161 size-full\" src=\"https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_4Opk9eMK8f0OBx7E18bwqw.png\" alt=\"Illustration : DX - DEV FLOW\" width=\"1200\" height=\"409\" srcset=\"https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_4Opk9eMK8f0OBx7E18bwqw-200x68.png 200w, https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_4Opk9eMK8f0OBx7E18bwqw-300x102.png 300w, https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_4Opk9eMK8f0OBx7E18bwqw-400x136.png 400w, https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_4Opk9eMK8f0OBx7E18bwqw-600x205.png 600w, https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_4Opk9eMK8f0OBx7E18bwqw-768x262.png 768w, https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_4Opk9eMK8f0OBx7E18bwqw-800x273.png 800w, https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_4Opk9eMK8f0OBx7E18bwqw-1024x349.png 1024w, https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_4Opk9eMK8f0OBx7E18bwqw.png 1200w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure>\r\n\r\n\r\n\r\n<p>&nbsp;<\/p>\r\n<p>That\u2019s it ! Should you have any question, please feel free to ask them in the comments or reach out to me on Twitter : <a href=\"https:\/\/www.twitter.com\/FabienTaillon\" target=\"_blank\" rel=\"noopener\">@FabienTaillon<\/a>.<\/p>\r\n\r\n\r\n\r\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\r\n<p><strong>Update<\/strong><\/p>\r\n<\/blockquote>\r\n\r\n\r\n\r\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\r\n<p>Salesforce just released a Trailhead Module and a Quick Start on Unlocked Packages. Seems a good start for everyone curious about DCPs :<\/p>\r\n<\/blockquote>\r\n\r\n\r\n\r\n<figure class=\"wp-block-embed\">\r\n<div class=\"wp-block-embed__wrapper\">https:\/\/trailhead.salesforce.com\/modules\/unlocked-packages-for-customers<\/div>\r\n<\/figure>\r\n\r\n\r\n\r\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\r\n<p>Note : In Summer \u201918, some CLI commands used for Second Generation Packages did changed, but the whole idea remains the same. You can have a look <a href=\"https:\/\/releasenotes.docs.salesforce.com\/en-us\/summer18\/release-notes\/rn_sfdx_packaging_commands.htm#rn_sfdx_packaging_commands\" target=\"_blank\" rel=\"noopener\">here <\/a>to see the list of what has changed.<\/p>\r\n<\/blockquote>\r\n","protected":false},"excerpt":{"rendered":"<p>Since the Spring \u201918, Second-Generation Packages can be installed in Production orgs. Three days after the release went out, we had our first DCP installed in Production. I\u2019m very excited about this new tool, and thought it could be interesting to share our journey with it. What is a Developer-Controlled Package\u00a0? Except if you\u2019ve been [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":2158,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[300],"tags":[],"class_list":["post-108","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-advices"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Our move to Salesforce DX and Developer-Controlled Packages - Texe\u00ef<\/title>\n<meta name=\"description\" content=\"What is a Developer-Controlled Package\u00a0? Selecting a\u00a0project. Creating a\u00a0Package2. Creating &amp; Installing a Package2\u00a0Version ...\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Our move to Salesforce DX and Developer-Controlled Packages\" \/>\n<meta property=\"og:description\" content=\"What is a Developer-Controlled Package\u00a0? Selecting a\u00a0project. Creating a\u00a0Package2. Creating &amp; Installing a Package2\u00a0Version ...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/\" \/>\n<meta property=\"og:site_name\" content=\"Texe\u00ef\" \/>\n<meta property=\"article:published_time\" content=\"2018-03-26T12:07:43+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-08-16T13:21:35+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_NOUapXeCDb8YnKGcp3woKQ.png\" \/>\n\t<meta property=\"og:image:width\" content=\"800\" \/>\n\t<meta property=\"og:image:height\" content=\"418\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Fabien Taillon\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/texei.com\\\/en\\\/advices\\\/our-move-to-salesforce-dx-and-developer-controlled-packages\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/texei.com\\\/en\\\/advices\\\/our-move-to-salesforce-dx-and-developer-controlled-packages\\\/\"},\"author\":{\"name\":\"Fabien Taillon\",\"@id\":\"https:\\\/\\\/texei.com\\\/#\\\/schema\\\/person\\\/082ce6d13635571cae4161f1d4f5a9a7\"},\"headline\":\"Our move to Salesforce DX and Developer-Controlled Packages\",\"datePublished\":\"2018-03-26T12:07:43+00:00\",\"dateModified\":\"2023-08-16T13:21:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/texei.com\\\/en\\\/advices\\\/our-move-to-salesforce-dx-and-developer-controlled-packages\\\/\"},\"wordCount\":1760,\"publisher\":{\"@id\":\"https:\\\/\\\/texei.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/texei.com\\\/en\\\/advices\\\/our-move-to-salesforce-dx-and-developer-controlled-packages\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/texei.com\\\/dev\\\/wp-content\\\/uploads\\\/2018\\\/03\\\/1_NOUapXeCDb8YnKGcp3woKQ.png\",\"articleSection\":[\"Advices\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/texei.com\\\/en\\\/advices\\\/our-move-to-salesforce-dx-and-developer-controlled-packages\\\/\",\"url\":\"https:\\\/\\\/texei.com\\\/en\\\/advices\\\/our-move-to-salesforce-dx-and-developer-controlled-packages\\\/\",\"name\":\"Our move to Salesforce DX and Developer-Controlled Packages - Texe\u00ef\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/texei.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/texei.com\\\/en\\\/advices\\\/our-move-to-salesforce-dx-and-developer-controlled-packages\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/texei.com\\\/en\\\/advices\\\/our-move-to-salesforce-dx-and-developer-controlled-packages\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/texei.com\\\/dev\\\/wp-content\\\/uploads\\\/2018\\\/03\\\/1_NOUapXeCDb8YnKGcp3woKQ.png\",\"datePublished\":\"2018-03-26T12:07:43+00:00\",\"dateModified\":\"2023-08-16T13:21:35+00:00\",\"description\":\"What is a Developer-Controlled Package\u00a0? Selecting a\u00a0project. Creating a\u00a0Package2. Creating & Installing a Package2\u00a0Version ...\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/texei.com\\\/en\\\/advices\\\/our-move-to-salesforce-dx-and-developer-controlled-packages\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/texei.com\\\/en\\\/advices\\\/our-move-to-salesforce-dx-and-developer-controlled-packages\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/texei.com\\\/en\\\/advices\\\/our-move-to-salesforce-dx-and-developer-controlled-packages\\\/#primaryimage\",\"url\":\"https:\\\/\\\/texei.com\\\/dev\\\/wp-content\\\/uploads\\\/2018\\\/03\\\/1_NOUapXeCDb8YnKGcp3woKQ.png\",\"contentUrl\":\"https:\\\/\\\/texei.com\\\/dev\\\/wp-content\\\/uploads\\\/2018\\\/03\\\/1_NOUapXeCDb8YnKGcp3woKQ.png\",\"width\":800,\"height\":418,\"caption\":\"Our move to Salesforce DX\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/texei.com\\\/en\\\/advices\\\/our-move-to-salesforce-dx-and-developer-controlled-packages\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/texei.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Advices\",\"item\":\"https:\\\/\\\/texei.com\\\/en\\\/category\\\/advices\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Our move to Salesforce DX and Developer-Controlled Packages\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/texei.com\\\/#website\",\"url\":\"https:\\\/\\\/texei.com\\\/\",\"name\":\"Texe\u00ef\",\"description\":\"Turn your IT into Business\",\"publisher\":{\"@id\":\"https:\\\/\\\/texei.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/texei.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/texei.com\\\/#organization\",\"name\":\"Texe\u00ef\",\"url\":\"https:\\\/\\\/texei.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/texei.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/texei.com\\\/dev\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/logo-essai-1.jpg\",\"contentUrl\":\"https:\\\/\\\/texei.com\\\/dev\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/logo-essai-1.jpg\",\"width\":2560,\"height\":1102,\"caption\":\"Texe\u00ef\"},\"image\":{\"@id\":\"https:\\\/\\\/texei.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/texei.com\\\/#\\\/schema\\\/person\\\/082ce6d13635571cae4161f1d4f5a9a7\",\"name\":\"Fabien Taillon\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/texei.com\\\/dev\\\/wp-content\\\/uploads\\\/2025\\\/12\\\/avatar_user_5_1766076207-96x96.png\",\"url\":\"https:\\\/\\\/texei.com\\\/dev\\\/wp-content\\\/uploads\\\/2025\\\/12\\\/avatar_user_5_1766076207-96x96.png\",\"contentUrl\":\"https:\\\/\\\/texei.com\\\/dev\\\/wp-content\\\/uploads\\\/2025\\\/12\\\/avatar_user_5_1766076207-96x96.png\",\"caption\":\"Fabien Taillon\"},\"url\":\"https:\\\/\\\/texei.com\\\/en\\\/author\\\/fabient\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Our move to Salesforce DX and Developer-Controlled Packages - Texe\u00ef","description":"What is a Developer-Controlled Package\u00a0? Selecting a\u00a0project. Creating a\u00a0Package2. Creating & Installing a Package2\u00a0Version ...","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/","og_locale":"en_US","og_type":"article","og_title":"Our move to Salesforce DX and Developer-Controlled Packages","og_description":"What is a Developer-Controlled Package\u00a0? Selecting a\u00a0project. Creating a\u00a0Package2. Creating & Installing a Package2\u00a0Version ...","og_url":"https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/","og_site_name":"Texe\u00ef","article_published_time":"2018-03-26T12:07:43+00:00","article_modified_time":"2023-08-16T13:21:35+00:00","og_image":[{"width":800,"height":418,"url":"https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_NOUapXeCDb8YnKGcp3woKQ.png","type":"image\/png"}],"author":"Fabien Taillon","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/#article","isPartOf":{"@id":"https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/"},"author":{"name":"Fabien Taillon","@id":"https:\/\/texei.com\/#\/schema\/person\/082ce6d13635571cae4161f1d4f5a9a7"},"headline":"Our move to Salesforce DX and Developer-Controlled Packages","datePublished":"2018-03-26T12:07:43+00:00","dateModified":"2023-08-16T13:21:35+00:00","mainEntityOfPage":{"@id":"https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/"},"wordCount":1760,"publisher":{"@id":"https:\/\/texei.com\/#organization"},"image":{"@id":"https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/#primaryimage"},"thumbnailUrl":"https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_NOUapXeCDb8YnKGcp3woKQ.png","articleSection":["Advices"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/","url":"https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/","name":"Our move to Salesforce DX and Developer-Controlled Packages - Texe\u00ef","isPartOf":{"@id":"https:\/\/texei.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/#primaryimage"},"image":{"@id":"https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/#primaryimage"},"thumbnailUrl":"https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_NOUapXeCDb8YnKGcp3woKQ.png","datePublished":"2018-03-26T12:07:43+00:00","dateModified":"2023-08-16T13:21:35+00:00","description":"What is a Developer-Controlled Package\u00a0? Selecting a\u00a0project. Creating a\u00a0Package2. Creating & Installing a Package2\u00a0Version ...","breadcrumb":{"@id":"https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/#primaryimage","url":"https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_NOUapXeCDb8YnKGcp3woKQ.png","contentUrl":"https:\/\/texei.com\/dev\/wp-content\/uploads\/2018\/03\/1_NOUapXeCDb8YnKGcp3woKQ.png","width":800,"height":418,"caption":"Our move to Salesforce DX"},{"@type":"BreadcrumbList","@id":"https:\/\/texei.com\/en\/advices\/our-move-to-salesforce-dx-and-developer-controlled-packages\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/texei.com\/"},{"@type":"ListItem","position":2,"name":"Advices","item":"https:\/\/texei.com\/en\/category\/advices\/"},{"@type":"ListItem","position":3,"name":"Our move to Salesforce DX and Developer-Controlled Packages"}]},{"@type":"WebSite","@id":"https:\/\/texei.com\/#website","url":"https:\/\/texei.com\/","name":"Texe\u00ef","description":"Turn your IT into Business","publisher":{"@id":"https:\/\/texei.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/texei.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/texei.com\/#organization","name":"Texe\u00ef","url":"https:\/\/texei.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/texei.com\/#\/schema\/logo\/image\/","url":"https:\/\/texei.com\/dev\/wp-content\/uploads\/2021\/03\/logo-essai-1.jpg","contentUrl":"https:\/\/texei.com\/dev\/wp-content\/uploads\/2021\/03\/logo-essai-1.jpg","width":2560,"height":1102,"caption":"Texe\u00ef"},"image":{"@id":"https:\/\/texei.com\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/texei.com\/#\/schema\/person\/082ce6d13635571cae4161f1d4f5a9a7","name":"Fabien Taillon","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/texei.com\/dev\/wp-content\/uploads\/2025\/12\/avatar_user_5_1766076207-96x96.png","url":"https:\/\/texei.com\/dev\/wp-content\/uploads\/2025\/12\/avatar_user_5_1766076207-96x96.png","contentUrl":"https:\/\/texei.com\/dev\/wp-content\/uploads\/2025\/12\/avatar_user_5_1766076207-96x96.png","caption":"Fabien Taillon"},"url":"https:\/\/texei.com\/en\/author\/fabient\/"}]}},"_links":{"self":[{"href":"https:\/\/texei.com\/en\/wp-json\/wp\/v2\/posts\/108","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/texei.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/texei.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/texei.com\/en\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/texei.com\/en\/wp-json\/wp\/v2\/comments?post=108"}],"version-history":[{"count":0,"href":"https:\/\/texei.com\/en\/wp-json\/wp\/v2\/posts\/108\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/texei.com\/en\/wp-json\/wp\/v2\/media\/2158"}],"wp:attachment":[{"href":"https:\/\/texei.com\/en\/wp-json\/wp\/v2\/media?parent=108"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/texei.com\/en\/wp-json\/wp\/v2\/categories?post=108"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/texei.com\/en\/wp-json\/wp\/v2\/tags?post=108"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}