Manage your Gitpod workspaces with your GitLab CI/CD workflow

Jean-Phi Baconnais - Jan 19 - - Dev Community

🤖 The Gitpod CLI

A few weeks ago, Gitpod released its CLI, offering some commands to interact with our workspaces. This is a great feature and I enjoy using it.

You can find information on the Gitpod documentation here or on the Cheatsheet I published on dev.to.

Gitpod CLI Cheatsheet

If you don't know what CLI is, it’s for Command Line Interface. It executes some actions with only commands, no UI. Globally used by people who love spending time on the Terminal or by people scripting actions.
Scripts on your laptop allow you to avoid writing a list of commands but in the area of CI/CD, we use it to create pipelines to automate actions for our projects.

Me? I like playing with CI/CD on GitLab. When I learned Gitpod released a CLI, after testing it on my laptop, I thought of using it in GitLab CI. Why?

🤷 Why use Gitpod CLI in CI/CD?

When you are going to work on a project, which steps do you take?

You create an issue. You often continue initiating a draft merge request (if not the case I recommend you to do that).

If you frequently use Gitpod and GItLab, you know that you can open (and create) a Gitpod workspace with only one click in the GitLab UI. After making your changes, you go to your Gitpod dashboard and delete your workspace.

Nothing complicated. But WAIT 🤔 you click on one button to launch a workspace. To close it after your work, you open a new tab, go to https://gitpod.io/, select a workspace and delete it.
These are only a few operations but if you make these operations several times a day, it can get repetitive 🤯

I love setting up CI/CD pipelines on GitLab, and thought how great it would be to execute these commands for me.

💪 Let’s sum up the objective of this experimentation

First, create a branch (directly from branch menu or from a merge request):

Create a branch on GitLab

Next, create a Gitpod workspace for my branch:

Gitpod workspace

Delete this workspace (from Pipeline or Environment menu).

Let’s develop this feature ✨

🛠️ Install Gitpod CLI

Before creating a GitLab CI pipeline, we need to declare a CI/CD variable GITPOD_CLI_TOKEN with the value of one Gitpod token.

Next, we have to install the CLI: easy! We create a job containing all commands in a before_script:

.gitpod-cli:
    before_script:
        - wget -O gitpod https://gitpod.io/static/bin/gitpod-cli-linux-amd64
        - chmod +x gitpod
        - ./gitpod login --token $GITPOD_CLI_TOKEN
Enter fullscreen mode Exit fullscreen mode

After this, we can see the Gitpod CLI is ready to be used 😁

Configure Gitpod CLI

Gitpod CLI is ready to use

🚀 Create a Gitpod workspace

The main command of the CLI is gitpod workspace. It allows you to create, delete, start, stop, list, etc your workspaces.

Gitpod workspace command

This new job, extending the previous one getting the CLI, creates the workspace with the gitpod workspace create command:

⚙️ configure-gitpod-workspace:
    script:
        - WS_ID=$(./gitpod workspace create $CI_PROJECT_URL/-/tree/$BRANCH_NAME --dont-wait) 
Enter fullscreen mode Exit fullscreen mode

New Gitpod workspace

I used the --dont-wait attribute in order not to wait for the state of my workspace. I only need the generated environment id that I put in an env file defined as an artifact report:

artifacts:
        reports:
            dotenv: gitpod.env
Enter fullscreen mode Exit fullscreen mode

I could stop these commands here, but I would like to have all the information in GitLab. For this, we can use the GitLab Environment and this script allows us to initiate a new environment containing the url to the Gitpod workspace:

environment:
        name: gitpod-env/$CI_COMMIT_REF_SLUG
        url: $GITPOD_WS_URL/#$WS_ID
Enter fullscreen mode Exit fullscreen mode

I use the gitpod-envprefix to avoid mixing these environments with the “classical” environments such as “dev”, “staging”, “production” etc.

GitLab environments

❌ Stop a Gitpod workspace

Since we started a Gitpod workspace using the CLI, it would be good to close it the same way!

In GitLab CI, you can add the on_stop attribute on the environment to set a job call when you decide to close the environment on the GitLab UI.

on_stop: delete_gitpod_workspace
Enter fullscreen mode Exit fullscreen mode

The delete_gitpod_workspace job has a simple script that calls the Gitpod CLI and the gitpod workspace delete command.

script:
    - ./gitpod workspace delete $WS_ID
Enter fullscreen mode Exit fullscreen mode

Cleaning is done ✅!

Cleaning Gitpod workspaces

With these jobs, we can manipulate our workspaces directly on GitLab and without any actions from us. Great!

GitLab CICD pipeline

But …

👀 Rules to execute theses jobs

Our CI/CD pipeline is running at each commit. I don’t know at which frequency you commit, but for me, it’s after each part of the feature or bug I am working on. As the CI/CD creates one Gitpod workspace for one commit, it can be too much.

GitLab CICD pipeline with jobs

I found this “hack” which prevents me from this behavior and creates only one Gitpod workspace by branch. I’m sure there is a better way to do this. Let me know if you know of any alternative ways!

My hack is to use the previous commit declared in this GitLab predefined variable CI_COMMIT_BEFORE_SHA. A value equal to '0000000000000000000000000000000000000000' specifies that it is the first commit. It’s a temporary hack right ? 😅

rules:
   - if: $CI_COMMIT_BEFORE_SHA == '0000000000000000000000000000000000000000' 
Enter fullscreen mode Exit fullscreen mode

And to avoid having one pipeline from an event of a merge request, let's add the rule $CI_PIPELINE_SOURCE != 'merge_request_event'.

You can find this project on my personal GitLab.

🔭 Next steps

This is just a taste of what is possible with the Gitpod CLI and GitLab CI/CD. In case you missed it, Pauline (DevRel + Community at Gitpod) recently wrote guide showcasing how to create self-serve preview environments with Gitpod and GitLab.

We can extend this further for example, by deleting the Gitpod workspace when a merge request (MR) is closed. This can be done if a “find” command was available which it currently is not, but I’ve raised this issue to discuss this use case.

I’ll continue playing around with the Gitpod CLI to include in my next project: my first GitLab CI/CD catalog. Stay tuned!

If you have any comments or suggestions, you can ping me on different social networks (Twitter/X, Linkedin, Bluesky, Mastodon or on dev.to).

Thanks to Severine and Pauline Narvas for your reviews 🙏

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .