CLI Scripting

The CLI provides a powerful interface for interacting with your packages and repositories in Cloudsmith. However, some operations currently require additional scripting to achieve the required result. Please see the examples below:

Copying/Moving Multiple Packages

Currently it is only possible to directly move one package at a time. However, it is easy to script a solution for moving multiple packages.

The following command will list all the packages returned by YOUR-QUERY. Extract the relevant metadata and run the copy command for each.

cloudsmith ls pkg YOUR-ACCOUNT/YOUR-REPO -q 'YOUR-QUERY' -F json \
  | jq '.data[] | .namespace + "/" + .repository + "/" + .slug' -r \
  | xargs -Ipackage cloudsmith copy package YOUR-DEST-REPO


The destination is not qualified by a namespace (YOUR-ACCOUNT). This is because you can only copy/move packages from repositories within the same namespace.


You can remove the query (YOUR-QUERY) to target all packages. The only downside to this approach is that it might require multiple invocations if you have more packages than the page size limit.

It's possible to navigate pages using -p and increase the page size limit to 500 using -l 500

The following moves all Maven packages named cloudsmith-api with version 0.21.* from lskillen/test2 to lskillen/test3. (Permissions permitting obviously)

cloudsmith ls pkg lskillen/test2 -q 'format:maven AND name:cloudsmith-api AND version:^0.21' -F json | jq '.data[] | .namespace + "/" + .repository + "/" + .slug' -r | xargs -Ipackage cloudsmith copy package test3

Waiting for a package to complete synchronizing

The wait_for_package_sync function below will wait for a package matching the provided query to either complete syncing or fail.

For example wait_for_package_sync "name:^foo$ AND version:0.0.1" would wait for a package named foo with version 0.0.1 to either successfully complete synchronization, fail or time out after 180 seconds.

The full list of available search parameters can be found in our documentation on searching and filtering.

get_package_identifier() {
    local query=${1:-""}
    cloudsmith list packages --output-format json --query "$query" "$ORG/$REPOSITORY" 2> /dev/null | jq '.data[0].slug' | sed -e 's/^"//' -e 's/"$//'

get_package_status() {
    local identifier=${1:-""}
    cloudsmith status "$ORG/$REPOSITORY/$identifier" 2> /dev/null

wait_for_package_sync() {
    local query=${1:-""}
    local total_time_limit=${2:-180}
    local identifier=""
    local package_status=""
    local total_time=0
    local identifier=""
    local package_sync_complete=1
    local package_sync_failed=0
    local sleep_time=10

    while [[ $total_time -lt $total_time_limit ]]; do
        if [[ -z "$identifier" ]] || [[ "$identifier" == "null" ]]; then
            identifier=$(get_package_identifier "$query")
            if [[ -z "$identifier" ]] || [[ "$identifier" == "null" ]]; then
              echo "Waiting for package .. (query: $query)" > /dev/stderr
              sleep $sleep_time

        package_status=$(get_package_status "$identifier")

        echo "$package_status" | grep --quiet 'Completed'

        echo "$package_status" | grep --quiet 'Failed'

        if [[ $package_sync_complete -eq 0 ]] || [[ $package_sync_failed -eq 0 ]]; then

        echo "Waiting for package status ... (identifier: $identifier)" > /dev/stderr
        sleep $sleep_time

    if [[ $total_time -gt $total_time_limit ]]; then
        echo "Timed out after waiting $total_time seconds for package to sync" > /dev/stderr
        exit 1

    if [[ $package_sync_complete -ne 0 ]]; then
      echo "Package failed to sync after $total_time seconds" > /dev/stderr
      exit 1

    echo "Package synced successfully after $total_time seconds" > /dev/stderr

Cloudsmith is the new standard in Package / Artifact Management and Software Distribution

With support for all major package formats, you can trust us to manage your software supply chain.

Start My Free Trial Now
Cookie Declaration (Manage Cookies)