Skip to main content

Creating Custom Reports using the Upsun CLI

Does X exist?

Someone recently asked me
Does a tool / report exist for the last deployment date for production sites - this will help find out if our sites are… out of date?
There isn’t a single pane in the console that list all the sites in your organization with the last date of a push to the production branch. But, one of the amazing things about Upsun is that our product is API-first. Whether you are performing an action in the Console, or using the CLI, they’re both just calling the API for you. The Upsun API itself is extensive and gives you everything you need in order to build just about anything you can imagine. And a report showing this information is entirely achievable! The Upsun CLI is really just a convenient wrapper for you to access the API from the command line, so for this example, I’ll use the CLI, but you can accomplish the exact same task using the API directly (or the recent Upsun PHP SDK). The other nice thing about the CLI is that it has a built-in multi command that allows you to perform the same command against multiple projects at once. To use it, you hand it a comma separated list of project IDs and then the command you want to perform on each one.

First we need IDs

For this example, I want the date of the last deployment (or push activity event) for my projects that start with the title “Template | ”. Since I know multi needs a list of project IDs, I’ll need to get those first. To grab a list of projects by their title, I can use the project:list command with the --title parameter to filter on the project title.
❯ upsun project:list --title="Template |"
This will produce something like
+---------------+--------------------------------------+------------------+-----------------+----------+
| ID            | Title                                | Region           | Org name        | Org type |
+---------------+--------------------------------------+------------------+-----------------+----------+
| qcelmtcwrzasy | Template | Akeneo                    | eu-3.platform.sh | devrel-projects | flex     |
| rmsh4dvlxfzoq | Template | Apache TomEE MicroProfile | eu-3.platform.sh | devrel-projects | flex     |
| 2kykonmslzfw2 | Template | ASP.NET Core              | eu-3.platform.sh | devrel-projects | flex     |
| bf6tpupauqym2 | Template | Backdrop                  | eu-3.platform.sh | devrel-projects | flex     |
<snip>
+---------------+--------------------------------------+------------------+-----------------+----------+
I don’t need anything besides the IDs, so I’ll adjust the command to only include the ID column, no header and a plain output:
❯ upsun project:list --title="Template |" --columns=id --format=plain --no-header
qcelmtcwrzasy
rmsh4dvlxfzoq
2kykonmslzfw2
bf6tpupauqym2
<snip>
I need to convert this into a comma separated list to use with the multi so I’ll pipe the output from this command to tr (translate) to transform newlines to commas. Note: I’m going to limit the number of projects to 5 using the --count parameter just to make this easier to show.
❯ upsun project:list --title="Template |" --count=5 --columns=id --format=plain --no-header | tr '\n' ','
qcelmtcwrzasy,rmsh4dvlxfzoq,2kykonmslzfw2,bf6tpupauqym2,cpxnqz5mjulbe,

Finding the date of the last deploy

Now that we have the list of project IDs, we can pass this information to the multi command. But before we do that, we need to know how to get the date of the last deployment of a project. Every time you push a change to an active environment, Upsun will deploy that change, rebuilding the containers if necessary. With that in mind, we need to find when the last push occurred to project’s default environment. For purposes of this example, we’re going to assume that all of our projects are using the same production branch name of main. One of the things the API exposes about your project is every activity that occurs to the project. In the CLI, we can use the activity:list command to retrieve all activities in a project.
❯ upsun activity:list --project bf6tpupauqym2 --environment main
Activities on the project Template | Backdrop (bf6tpupauqym2), environment main (type: production):
+---------------+---------------------------+-----------------------------------------------------------------+----------+----------+---------+
| ID            | Created                   | Description                                                     | Progress | State    | Result  |
+---------------+---------------------------+-----------------------------------------------------------------+----------+----------+---------+
| gth4nqryisjmu | 2025-11-12T04:19:54+00:00 | Platform.sh Bot deleted backup o5bcracgspyejya6k6k7udtb6y       | 100%     | complete | success |
| i22xaywuudqmw | 2025-11-12T04:19:45+00:00 | Platform.sh Bot created a backup of Main                        | 100%     | complete | success |
| 5qbh7ajrtrmxw | 2025-11-11T04:19:54+00:00 | Platform.sh Bot deleted backup wwgnegtoybnkxho4re5lckqsm4       | 100%     | complete | success |
| vnzlijtgdycqa | 2025-11-11T04:19:45+00:00 | Platform.sh Bot created a backup of Main                        | 100%     | complete | success |<snip>
<snip>
+---------------+---------------------------+-----------------------------------------------------------------+----------+----------+---------+
We’re only interested in push activities so let’s add the --type parameter to limit the returned activities to only push events.
❯ upsun activity:list --project bf6tpupauqym2 --environment main --type=push
Activities on the project Template | Backdrop (bf6tpupauqym2), environment main (type: production):
+---------------+---------------------------+-------------------------------------+----------+----------+---------+
| ID            | Created                   | Description                         | Progress | State    | Result  |
+---------------+---------------------------+-------------------------------------+----------+----------+---------+
| xohtyme4hdcvc | 2025-10-24T19:14:01+00:00 | GitHub integration pushed to Main   | 100%     | complete | success |
| zzt2ri5gzccx6 | 2025-10-23T14:30:56+00:00 | GitHub integration pushed to Main   | 100%     | complete | success |
+---------------+---------------------------+-------------------------------------+----------+----------+---------+
Note: The actual activity type name for a push activity event is environment.push. However, the CLI allows us to omit the first part of an activity’s name for convenience.
We only want the most recent push event AND we only want the date, so let’s add in a --limit of 1 (the default is to sort by activity date - Created - descending) and select only the Created column. We also don’t need the table format or header, so let’s use --format=plain and --no-header to remove those.
❯ upsun activity:list --project bf6tpupauqym2 --environment main --type=push --columns=created --limit=1 --format=plain --no-header
2025-10-24T19:14:01+00:00
Perfect! We now have the exact command we need to retrieve the last push activity to hand to the multi command!

Combing the commands to generate our report

Let’s combine this command with the multi command and use the command to retrieve our project IDs from earlier to get a complete report on the last time each project had a push event!
❯ upsun multi --projects=$(upsun project:list --title="Template |" --count=5 --columns=id --format=plain --no-header | tr '\n' ',') -- activity:list --environment main --type=push --columns=created --limit=1 --format=plain --no-header
Running command on 5 projects:  'activity:list' '--environment' 'main' '--type=push' '--columns=created' '--limit=1' '--format=plain' '--no-header'
# Project: Template | Akeneo (qcelmtcwrzasy)
2025-10-27T13:26:28+00:00
# Project: Template | Apache TomEE MicroProfile (rmsh4dvlxfzoq)
No activities found
# Project: Template | ASP.NET Core (2kykonmslzfw2)
No activities found
# Project: Template | Backdrop (bf6tpupauqym2)
2025-10-23T14:30:56+00:00
# Project: Template | Beego (cpxnqz5mjulbe)
2025-11-11T19:31:12+00:00
I now have a report where I can see the last time each of my projects were pushed to, and surprise: I now see that for at least two projects, it has been long enough since they received a push that the push event activity log has expired!

Go forth and report

I hope this has given you some ideas on the flexibility and power the Upsun API possesses and how you can utilize this to create your own reports catered to your unique business needs, even when what you need doesn’t already exist.

Bonus items

Date Format

It’s possible you’ll need that activity date in a different format. Don’t worry: we’ve got you covered. The activity:list command accepts a --date-fmt parameter allowing you to alter the date format using a PHP date format string.

Limit to successful pushes

In the example above, the person asking for the report wanted any push events to the project. It’s possible though in your situation that you only want those where the push (and build) was successful. To filter to those events where the result of a push was successful, we can add the --result parameter with a value of success to our activity:list command.

Simplified command option if you want everything

In the example I used, I needed to limit the number of IDs returned from the project:list command to just 5 to make the example easier to read. If you don’t need to limit the number of projects to a smaller amount than what matches, you can simplify the project:list command by using the --pipe parameter, which returns a simple list of project IDs, disabling any pagination in the returned results. In our example, adding the --pipe parameter would result in a much more succinct command:
❯ upsun project:list --title="Template |" --pipe
qcelmtcwrzasy
rmsh4dvlxfzoq
2kykonmslzfw2
bf6tpupauqym2
<snip>

My projects don’t all use the same production branch name

While standardization is great and should be the ideal, reality isn’t always so cooperative. Perhaps you inherited a project, or some projects were set up before you standardized on the production name. In order to accomplish the example above, we need some ability to retrieve the production branch name in order to pass that to the upsun multi command. We could perform a preliminary upsun multi command that retrieves each project’s default_branch using the upsun project:info command. However, this adds significant complexity to what we’re trying to achieve. Our CLI attempts to be very accommodating and make things easier on our users. That includes the ability to use a period (.) to represent a project’s default environment! This allows us to update our previous command to work with all our projects even if they do not use the same default_branch name!
❯ upsun multi --projects=$(upsun project:list --title="Template |" --count=5 --columns=id --format=plain --no-header | tr '\n' ',') -- activity:list --environment . --type=push --columns=created --limit=1 --format=plain --no-header
Running command on 5 projects:  'activity:list' '--environment' '.' '--type=push' '--columns=created' '--limit=1' '--format=plain' '--no-header'

# Project: Template | Akeneo (qcelmtcwrzasy)
Selecting default environment (indicated by .)
Selected environment: main (type: production)
2025-10-27T13:26:28+00:00

# Project: Template | Apache TomEE MicroProfile (rmsh4dvlxfzoq)
Selecting default environment (indicated by .)
Selected environment: main (type: production)
No activities found

# Project: Template | ASP.NET Core (2kykonmslzfw2)
Selecting default environment (indicated by .)
Selected environment: main (type: production)
No activities found

# Project: Template | Backdrop (bf6tpupauqym2)
Selecting default environment (indicated by .)
Selected environment: main (type: production)
2025-10-23T14:30:56+00:00

# Project: Template | Beego (cpxnqz5mjulbe)
Selecting default environment (indicated by .)
Selected environment: main (type: production)
2025-11-11T19:31:12+00:00
Last modified on April 14, 2026