A complete SalesForce app pipeline #3: Creating packages
In the previous two parts we have set up an automated GitLab CI/CD pipeline where we pushed our code into a new scratch org, and created a script running automated tests. So at this moment our code is consistent (because it can be pushed into a new org) and error-free (the tests should guarantee it).
If everything is good, it’s time to create packages! In fact, this is a very easy task using SFDX: all we want to do is to run one command! I’ve added some extra code which makes the things nicer — so let’s examine the code!

Note: this post is about creating first-generation packages (‘normal Salesforce packages’). If you want to learn about second-generation packages, read this post.
This is only a part of the .gitlab-ci.yml file (for the whole file, see the first part or scroll down). As you see, this part runs only when something is pushed to the master
branch. The idea is that when the master is updated, it should be packaged immediately (but it can be different in your workflow!)
The first line is a simple authentication: force:auth:jwt:grant
In the second line, we push the code to the org ( force:source:deploy
). Note that instead of source:push
we use source:deploy
: this is because it is not a scratch-org, so only deploy is allowed.
In the next line we tell the org to create a package: force:package1:version:create
and write the result into a file. This is the same thing as clicking ‘Upload’ in your packaging org — but automated! Then, using the JQ utility, we get the id of the packaging job. This is because packaging takes time, and we need to ask server later about the result.
To figure out the result of the job, the force:package1:version:version:create:get
command is used. The first status is usually QUEUED, then IN_PROGRESS and finally SUCCESS.
That’s why there is a while-loop in the script: in runs and asks for the status until there is a SUCCESS.
And once there is a success, we have the Id of the new package — which can be used in the install-url — and we can email it immediately to our customer (or maybe before this, do some manual testing:)
If you want to see the whole yaml file, scroll down. In the next post, I’ll add some more sweet things which can make our salesforce package developer life even more easier!