Skip to content

Commit 888c231

Browse files
authored
feat: support self-hosted GitLab (ENG-3025) (#10)
Self-hosted GitLab environments lack ENV0_PR_SOURCE_REPOSITORY and GITLAB_TOKEN. This adds fallbacks so the plugin works out of the box: - Use ENV0_TEMPLATE_REPOSITORY to derive the GitLab API URL when ENV0_PR_SOURCE_REPOSITORY is unavailable - Accept ENV0_VCS_ACCESS_TOKEN as a fallback for GITLAB_TOKEN - Construct a stable MR URL as --ticket-link so Overmind deduplicates changes across multiple plans for the same merge request - Strip trailing .git from repository URLs Made-with: Cursor
1 parent 257b660 commit 888c231

2 files changed

Lines changed: 87 additions & 28 deletions

File tree

README.md

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,22 @@ This plugin integrates [Overmind](https://www.overmind.tech/) with env0 to track
55
## Overview
66

77
The Overmind plugin installs the Overmind CLI (and GitHub CLI) and executes one of four actions:
8+
89
- **submit-plan**: Submits a Terraform plan to Overmind for analysis
910
- **start-change**: Marks the beginning of a change in Overmind
1011
- **end-change**: Marks the completion of a change in Overmind
1112
- **wait-for-simulation**: Retrieves simulation output from Overmind and comments on the relevant GitHub PR or GitLab MR
1213

1314
## Inputs
1415

15-
| Input | Description | Required |
16-
|-------|-------------|----------|
17-
| `action` | The action to perform. Must be one of: `submit-plan`, `start-change`, `end-change`, `wait-for-simulation` | Yes |
18-
| `api_key` | Overmind API key for authentication. Must have the following scopes: `account:read`, `changes:write`, `config:write`, `request:receive`, `sources:read`, `source:write` | Yes |
19-
| `tags` | A comma-separated list of key=value tags to attach to the change (only used with `submit-plan` action) | No |
20-
| `post_comment` | Whether `wait-for-simulation` should post the Overmind markdown to GitHub PR or GitLab MR. Defaults to `true` when running against a PR/MR, otherwise `false`. When `true`, `comment_provider` must be set. | No |
21-
| `comment_provider` | Where `wait-for-simulation` should post comments when `post_comment=true`. Must be one of: `github`, `gitlab`. | No |
22-
| `on_failure` | Behavior when the plugin step errors. `fail` (default) fails the step and blocks the deployment; `pass` allows the deployment to continue even if this step errors. Must be one of: `fail`, `pass`. | No |
16+
| Input | Description | Required |
17+
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
18+
| `action` | The action to perform. Must be one of: `submit-plan`, `start-change`, `end-change`, `wait-for-simulation` | Yes |
19+
| `api_key` | Overmind API key for authentication. Must have the following scopes: `account:read`, `changes:write`, `config:write`, `request:receive`, `sources:read`, `source:write` | Yes |
20+
| `tags` | A comma-separated list of key=value tags to attach to the change (only used with `submit-plan` action) | No |
21+
| `post_comment` | Whether `wait-for-simulation` should post the Overmind markdown to GitHub PR or GitLab MR. Defaults to `true` when running against a PR/MR, otherwise `false`. When `true`, `comment_provider` must be set. | No |
22+
| `comment_provider` | Where `wait-for-simulation` should post comments when `post_comment=true`. Must be one of: `github`, `gitlab`. | No |
23+
| `on_failure` | Behavior when the plugin step errors. `fail` (default) fails the step and blocks the deployment; `pass` allows the deployment to continue even if this step errors. Must be one of: `fail`, `pass`. | No |
2324

2425
## Usage
2526

@@ -105,7 +106,7 @@ deploy:
105106
inputs:
106107
action: wait-for-simulation
107108
api_key: ${OVERMIND_API_KEY}
108-
post_comment: false # optional override
109+
post_comment: false # optional override
109110
```
110111

111112
If you want to post a comment, set `comment_provider` explicitly:
@@ -140,17 +141,48 @@ deploy:
140141
comment_provider: gitlab
141142
```
142143

143-
### Fail-safe: allow deployment to continue on plugin errors
144+
### Self-Hosted GitLab
144145

145-
By default, if the plugin step fails (e.g. Overmind API error, missing env var, network issue), env0 treats the step as failed and can block the deployment. To allow the deployment to continue even when this step errors, set `on_failure: pass`:
146+
For self-hosted GitLab environments where `ENV0_PR_SOURCE_REPOSITORY` is not available, the plugin falls back to `ENV0_TEMPLATE_REPOSITORY` to derive the GitLab API URL for posting merge request comments.
147+
148+
For authentication, the plugin uses `GITLAB_TOKEN` if set, otherwise falls back to `ENV0_VCS_ACCESS_TOKEN`. The token must have the GitLab `api` scope to post MR comments.
146149

147150
```yaml
151+
version: 2
152+
deploy:
153+
steps:
154+
terraformPlan:
155+
after:
148156
- name: Submit Plan to Overmind
149-
use: https://github.com/your-org/env0-plugin
157+
use: https://github.com/overmindtech/env0-plugin
150158
inputs:
151159
action: submit-plan
152160
api_key: ${OVERMIND_API_KEY}
153-
on_failure: pass # deployment continues even if this step fails
161+
162+
terraformApply:
163+
after:
164+
- name: Post Overmind Simulation (Self-Hosted GitLab)
165+
use: https://github.com/overmindtech/env0-plugin
166+
inputs:
167+
action: wait-for-simulation
168+
api_key: ${OVERMIND_API_KEY}
169+
post_comment: true
170+
comment_provider: gitlab
171+
```
172+
173+
No `GITLAB_TOKEN` is needed if `ENV0_VCS_ACCESS_TOKEN` is already available in your env0 environment.
174+
175+
### Fail-safe: allow deployment to continue on plugin errors
176+
177+
By default, if the plugin step fails (e.g. Overmind API error, missing env var, network issue), env0 treats the step as failed and can block the deployment. To allow the deployment to continue even when this step errors, set `on_failure: pass`:
178+
179+
```yaml
180+
- name: Submit Plan to Overmind
181+
use: https://github.com/your-org/env0-plugin
182+
inputs:
183+
action: submit-plan
184+
api_key: ${OVERMIND_API_KEY}
185+
on_failure: pass # deployment continues even if this step fails
154186
```
155187

156188
Use `on_failure: pass` when the Overmind integration is optional and you do not want plugin failures to block deployments.
@@ -170,7 +202,7 @@ deploy:
170202
inputs:
171203
action: submit-plan
172204
api_key: ${OVERMIND_API_KEY}
173-
205+
174206
terraformApply:
175207
before:
176208
- name: Mark Change Started
@@ -198,7 +230,7 @@ deploy:
198230
- `end-change`: Marks the completion of a change with a ticket link to the env0 deployment
199231
- `wait-for-simulation`: Retrieves Overmind simulation results as Markdown and (when `post_comment=true`) posts them to the GitHub PR or GitLab MR (automatically detected based on repository URL)
200232

201-
4. **Ticket Links**: All actions automatically construct a ticket link to the env0 deployment using environment variables (`ENV0_PROJECT_ID`, `ENV0_ENVIRONMENT_ID`, `ENV0_DEPLOYMENT_LOG_ID`, `ENV0_ORGANIZATION_ID`).
233+
4. **Ticket Links**: When `ENV0_PR_NUMBER` is set (i.e., the deployment is triggered by a PR/MR), the plugin constructs a stable merge request URL from `ENV0_PR_SOURCE_REPOSITORY` (or `ENV0_TEMPLATE_REPOSITORY` as a fallback) and `ENV0_PR_NUMBER`. This ensures multiple plans for the same MR update the same Overmind change. For non-PR deployments, the ticket link falls back to the env0 deployment URL.
202234

203235
## Requirements
204236

@@ -209,7 +241,7 @@ deploy:
209241
- `ENV0_ORGANIZATION_ID`
210242
- `ENV0_TF_PLAN_JSON` (for submit-plan action)
211243
- `ENV0_PR_NUMBER` (only when `wait-for-simulation` posts comments, i.e., running against a PR/MR)
212-
- `ENV0_PR_SOURCE_REPOSITORY` (only when `wait-for-simulation` posts comments, used to detect GitHub vs GitLab)
244+
- `ENV0_PR_SOURCE_REPOSITORY` (only when `wait-for-simulation` posts comments to GitHub; for GitLab, falls back to `ENV0_TEMPLATE_REPOSITORY`)
213245

214246
- A valid Overmind API key with the following required scopes:
215247
- `account:read`
@@ -220,7 +252,7 @@ deploy:
220252
- `source:write`
221253

222254
- GitHub authentication for the CLI when `wait-for-simulation` posts to GitHub (set `GH_TOKEN`).
223-
- GitLab authentication when `wait-for-simulation` posts to GitLab (set `GITLAB_TOKEN`).
255+
- GitLab authentication when `wait-for-simulation` posts to GitLab (set `GITLAB_TOKEN`, or rely on `ENV0_VCS_ACCESS_TOKEN` which is automatically available in self-hosted GitLab environments). The token must have the GitLab `api` scope.
224256

225257
### Creating a `GH_TOKEN`
226258

@@ -242,9 +274,9 @@ deploy:
242274
5. Store the token securely in env0 (for example as an environment variable or secret) and expose it to the plugin as `GITLAB_TOKEN`.
243275

244276
**Note**: When `post_comment=true`, you must set `comment_provider` to `github` or `gitlab`.
277+
245278
## Notes
246279

247280
- The plugin automatically detects the operating system and architecture to download the correct Overmind CLI binary.
248281
- The installation directory is automatically selected from writable directories in your PATH.
249282
- For the `submit-plan` action, the `ENV0_TF_PLAN_JSON` environment variable must be set (this is automatically provided by env0 after a terraform plan step).
250-

env0.plugin.yaml

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,21 @@ run:
213213
# Construct the env0 deployment URL for the ticket-link
214214
ticket_link="https://app.env0.com/p/${ENV0_PROJECT_ID}/environments/${ENV0_ENVIRONMENT_ID}/deployments/${ENV0_DEPLOYMENT_LOG_ID}?organizationId=${ENV0_ORGANIZATION_ID}"
215215
216+
# Override ticket_link with a stable MR/PR URL when available,
217+
# so Overmind deduplicates changes within the same MR/PR
218+
if [ -n "${ENV0_PR_NUMBER}" ]; then
219+
REPO_URL=""
220+
if [ -n "${ENV0_PR_SOURCE_REPOSITORY}" ]; then
221+
REPO_URL="${ENV0_PR_SOURCE_REPOSITORY}"
222+
elif [ -n "${ENV0_TEMPLATE_REPOSITORY}" ]; then
223+
REPO_URL="${ENV0_TEMPLATE_REPOSITORY}"
224+
fi
225+
if [ -n "${REPO_URL}" ]; then
226+
REPO_URL=$(echo "${REPO_URL}" | sed 's|\.git$||')
227+
ticket_link="${REPO_URL}/-/merge_requests/${ENV0_PR_NUMBER}"
228+
fi
229+
fi
230+
216231
# Build description from env0 deployment info
217232
description="Env0 Deployment: ${ENV0_PROJECT_NAME} - ${ENV0_ENVIRONMENT_NAME} (${ENV0_DEPLOYMENT_TYPE})"
218233
if [ -n "${ENV0_DEPLOYER_NAME}" ]; then
@@ -347,10 +362,6 @@ run:
347362
echo "Error: ENV0_PR_NUMBER environment variable is not set but post_comment=true"
348363
exit 1
349364
fi
350-
if [ -z "${ENV0_PR_SOURCE_REPOSITORY}" ]; then
351-
echo "Error: ENV0_PR_SOURCE_REPOSITORY environment variable is not set but post_comment=true"
352-
exit 1
353-
fi
354365
355366
comment_provider=$(echo "${inputs.comment_provider}" | tr '[:upper:]' '[:lower:]')
356367
if [ -z "${comment_provider}" ]; then
@@ -361,17 +372,28 @@ run:
361372
case "${comment_provider}" in
362373
gitlab)
363374
# GitLab merge request
364-
if [ -z "${GITLAB_TOKEN}" ]; then
365-
echo "Error: GITLAB_TOKEN environment variable is not set but comment_provider=gitlab"
375+
376+
# Fall back to ENV0_TEMPLATE_REPOSITORY for self-hosted GitLab
377+
# where ENV0_PR_SOURCE_REPOSITORY is not available
378+
if [ -n "${ENV0_PR_SOURCE_REPOSITORY}" ]; then
379+
REPO_STR="${ENV0_PR_SOURCE_REPOSITORY}"
380+
elif [ -n "${ENV0_TEMPLATE_REPOSITORY}" ]; then
381+
REPO_STR="${ENV0_TEMPLATE_REPOSITORY}"
382+
else
383+
echo "Error: Neither ENV0_PR_SOURCE_REPOSITORY nor ENV0_TEMPLATE_REPOSITORY is set"
366384
exit 1
367385
fi
368386
369-
# Extract GitLab base URL and project path from repository string
370-
# ENV0_PR_SOURCE_REPOSITORY format: "group/project" or "https://gitlab.com/group/project" or "gitlab.com/group/project"
371-
REPO_STR="${ENV0_PR_SOURCE_REPOSITORY}"
387+
# Fall back to ENV0_VCS_ACCESS_TOKEN for self-hosted GitLab
388+
GITLAB_TOKEN="${GITLAB_TOKEN:-${ENV0_VCS_ACCESS_TOKEN}}"
389+
if [ -z "${GITLAB_TOKEN}" ]; then
390+
echo "Error: Neither GITLAB_TOKEN nor ENV0_VCS_ACCESS_TOKEN is set"
391+
exit 1
392+
fi
372393
373-
# Remove protocol if present
394+
# Remove protocol and trailing .git if present
374395
REPO_STR=$(echo "${REPO_STR}" | sed 's|^https\?://||')
396+
REPO_STR=$(echo "${REPO_STR}" | sed 's|\.git$||')
375397
376398
# Extract host (default to gitlab.com if not specified)
377399
if echo "${REPO_STR}" | grep -q "/"; then
@@ -422,6 +444,11 @@ run:
422444
fi
423445
;;
424446
github)
447+
if [ -z "${ENV0_PR_SOURCE_REPOSITORY}" ]; then
448+
echo "Error: ENV0_PR_SOURCE_REPOSITORY environment variable is not set but comment_provider=github"
449+
exit 1
450+
fi
451+
425452
install_github_cli
426453
427454
# GitHub pull request

0 commit comments

Comments
 (0)