Publishing an Orb to multiple namespaces
Sometimes, an organization may wish to share a private orb with multiple organizations. Currently, private orbs are by definition restricted to a single organization.
However, this limitation can be circumvented by publishing an orb to multiple namespaces simultaneously. This can be integrated into the automated pipeline that deploys the orb. The overhead is minimal, making this a viable workaround for many users seeking this functionality.
An orb that is already being built, tested, and deployed in the conventional manner as outlined by the Orb Development Kit.
To deploy the orb to multiple namespaces, a copy of the “packed” orb created as part of the orb deployment pipeline is required. Small, necessary, but automated changes will be made to this copy, which is then deployed to the secondary namespace.
All of this behavior can be achieved by adding a single additional job to the existing test-deploy
workflow. The lint-pack
workflow will remain unchanged.
Conventionally, the packed orb exists in the workspace in orb.yml
. The first step is to copy this orb.
- run:
name: Create replica of the orb
command: cp dist/orb.yml dist/orb-replica-my-namespace-2.yml
This step is only strictly necessary if the orb uses other private orbs. It’s important to note that those other private orbs will already need to be published as replicas.
In such cases, the orb will be referencing orbs in a namespace it does not have access to.
For example:
orbs:
my-other-private-orb: my-namespace-1/my-private-orb@volatile
However, there isn’t access to private orbs in my-namespace-1
when publishing to my-namespace-2
.
Therefore, any of these references in the replica can be automatically updated.
# Update the replica's source to use its own organisations private orbs
# Note: this has not been extensively tested
- run:
name: Update private orb references in replica source
command: |
# Here we'll just refactor the YAML to replace any orbs from org-1 to use the namespace org-2
# note this could be more concise but this makes sure to gracefully handle inline orbs
ORIGINAL_ORG_NAME="org-1"
NEW_ORG_NAME="org-2"
SOURCE_FILE="dist/orb-replica.yml"
# Get list of keys under orbs
keys=$(yq '(.orbs | keys)[]' $SOURCE_FILE)
for key in $keys
do
# Trim key
key=$(echo $key | xargs)
# Get current value
value=$(yq ".orbs.\"$key\"" $SOURCE_FILE)
# If the value is a string containing "$ORIGINAL_ORG_NAME/",
if [[ $value == "${ORIGINAL_ORG_NAME}/"* ]]
then
echo "Updating $value to use $NEW_ORG_NAME"
# Note this line updates the yaml file in-place
yq e -i ".orbs.\"$key\" = \"${value//$ORIGINAL_ORG_NAME/$NEW_ORG_NAME}\"" $SOURCE_FILE
fi
done
The replica orb will now have no remaining references to the primary namespace (my-namespace-1
).
Technically, the above script might not catch everything if there are some inline orbs that use private orbs. However, this is not a common scenario.
E.g
orbs:
some-inline-orb:
orbs:
my-orb: private-namespace/my-orb@volatile
private-namespace
would not be caught here.
This replica is now ready to be published in the usual fashion. You can either do this manually or using the orb-tools
orb.
# Note this job needs a PAT for the replica org
- run:
name: Publish orb replica
# See `circleci orb publish` for full params
command: circleci orb publish dist/orb-replica-my-namespace-2.yml replica-namespace/my-orb
The orb-tools
orb only provides the publish function as a job, so you’ll need to add the replica to the workspace before the publish job runs.
# You'll already have an orb-tools/publish job in your workflow
- orb-tools/publish:
requires: [] #require your test jobs
context: [] # PAT context
# test-publish workflow
- create-replicas:
requires: [] # require your test jobs
# dist/orb-replica-my-namespace-2.yml needs to be added to the workspace in `create-replicas`
- orb-tools/publish:
name: publish-replica-my-namespace-2
requres: [create-replica]
context: [my-namespace-2-pat]
orb_file_name: dist/orb-replica-my-namespace-2.yml
orb_name: my-namespace-2/orb-name
In conclusion, with this approach, you should find that you are able to deploy a private orb to multiple organizations in a single pipeline with minimal fuss.