Manage your Gitpod workspaces with your GitLab CI/CD workflow
Tags: gitlab, gitpod, cicd, cde
Published: 2024-01-19 08:57:07

## 🤖 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](https://www.gitpod.io/docs/references/gitpod-cli) or on the Cheatsheet I published on [dev.to](https://dev.to/gitpod/gitpod-cli-cheatsheet-55hj). 

![Gitpod CLI Cheatsheet](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s6m6q72f4elvi6r0so4c.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aaapcng10iw7y43smgay.png)


Next, create a Gitpod workspace for my branch:

![Gitpod workspace](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/261ewrq4sqi4jlq2qd89.png)


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](https://gitpod.io/user/tokens).

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
```

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

![Configure Gitpod CLI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p9yd2sret780kn2e0off.jpeg)


![Gitpod CLI is ready to use](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h3vtoddxw0az6rsgrd3j.png)


## 🚀 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/we8e0eqdimy535vm49qf.png)

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) 
```

![New Gitpod workspace](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6phmmj18h0tya55h40qk.png)


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
``` 

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
```

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


![GitLab environments](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uayoripe82d4573d9ov3.png)


## ❌ 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
```

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
```

Cleaning is done ✅!


![Cleaning Gitpod workspaces](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xrrn1nxg95w2ae4w00db.png)


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


![GitLab CICD pipeline](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h8qz0r2d1zptqe96zypq.png)


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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cy551h2b4fys9x7mdbro.png)


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' 
```

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](https://gitlab.com/jeanphi-baconnais-experiments/playing-with-gitpod-cli).


## 🔭 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](https://twitter.com/paulienuh) (DevRel + Community at Gitpod) recently wrote [guide](https://www.gitpod.io/guides/create-self-serve-preview-environments-with-gitpod-and-gitlab) 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](https://github.com/gitpod-io/gitpod/issues/19312) 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](https://twitter.com/JPhi_Baconnais), [Linkedin](https://www.linkedin.com/in/jean-philippe-baconnais-931544116/), [Bluesky](https://bsky.app/profile/jeanphi-baconnais.bsky.social), [Mastodon](@jphi_baconnais@pwet.me) or on [dev.to](https://dev.to/jphi_baconnais)).

Thanks to [Severine](https://www.linkedin.com/in/severine-luzeau) and [Pauline Narvas](https://twitter.com/paulienuh) for your reviews 🙏