diff --git a/README.md b/README.md index 6e6430a..3dc57ff 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,8 @@ The Overmind plugin installs the Overmind CLI (and GitHub CLI) and executes one | `action` | The action to perform. Must be one of: `submit-plan`, `start-change`, `end-change`, `wait-for-simulation` | Yes | | `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 | | `tags` | A comma-separated list of key=value tags to attach to the change (only used with `submit-plan` action) | No | -| `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`. Automatically detects GitHub or GitLab based on repository URL. | No | +| `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 | +| `comment_provider` | Where `wait-for-simulation` should post comments when `post_comment=true`. Must be one of: `github`, `gitlab`. | No | ## Usage @@ -90,7 +91,7 @@ deploy: ### Wait for Simulation (any step after Overmind run) -Fetch the latest Overmind simulation summary for the current env0 deployment and (optionally) comment on the matching GitHub pull request or GitLab merge request. By default the plugin posts comments whenever the deployment runs in the context of a PR/MR; set `post_comment: false` to skip commenting. The plugin automatically detects whether the repository is GitHub or GitLab based on the repository URL. When posting to GitHub, make sure `GH_TOKEN` is set. When posting to GitLab, make sure `GITLAB_TOKEN` is set. +Fetch the latest Overmind simulation summary for the current env0 deployment and (optionally) comment on the matching GitHub pull request or GitLab merge request. By default the plugin posts comments whenever the deployment runs in the context of a PR/MR; set `post_comment: false` to skip commenting. When `post_comment=true`, you must set `comment_provider` to `github` or `gitlab`. When posting to GitHub, make sure `GH_TOKEN` is set. When posting to GitLab, make sure `GITLAB_TOKEN` is set. ```yaml version: 2 @@ -106,6 +107,38 @@ deploy: post_comment: false # optional override ``` +If you want to post a comment, set `comment_provider` explicitly: + +```yaml +version: 2 +deploy: + steps: + terraformApply: + after: + - name: Post Overmind Simulation (GitHub) + use: https://github.com/your-org/env0-plugin + inputs: + action: wait-for-simulation + api_key: ${OVERMIND_API_KEY} + post_comment: true + comment_provider: github +``` + +```yaml +version: 2 +deploy: + steps: + terraformApply: + after: + - name: Post Overmind Simulation (GitLab) + use: https://github.com/your-org/env0-plugin + inputs: + action: wait-for-simulation + api_key: ${OVERMIND_API_KEY} + post_comment: true + comment_provider: gitlab +``` + ### Complete Example Here's a complete example that uses the plan/change lifecycle actions: @@ -192,7 +225,7 @@ deploy: 4. Generate the token and copy it immediately—GitLab will not show it again. 5. Store the token securely in env0 (for example as an environment variable or secret) and expose it to the plugin as `GITLAB_TOKEN`. -**Note**: The plugin automatically detects whether a repository is GitHub or GitLab based on the `ENV0_PR_SOURCE_REPOSITORY` environment variable. If the repository URL contains "gitlab", it will use GitLab API; otherwise, it will use GitHub CLI. +**Note**: When `post_comment=true`, you must set `comment_provider` to `github` or `gitlab`. ## Notes - The plugin automatically detects the operating system and architecture to download the correct Overmind CLI binary. diff --git a/env0.plugin.yaml b/env0.plugin.yaml index c6e887f..9057f64 100644 --- a/env0.plugin.yaml +++ b/env0.plugin.yaml @@ -14,7 +14,10 @@ inputs: description: "The Overmind instance to connect to (defaults to https://app.overmind.tech)" required: false post_comment: - description: "Whether wait-for-simulation should post the Overmind markdown to the PR/MR. Defaults to true when ENV0_PR_NUMBER is set, otherwise false. Automatically detects GitHub or GitLab based on repository URL." + description: "Whether wait-for-simulation should post the Overmind markdown to the PR/MR. Defaults to true when ENV0_PR_NUMBER is set, otherwise false. When true, comment_provider must be set." + required: false + comment_provider: + description: "Where to post PR/MR comments when wait-for-simulation runs with post_comment=true. Must be one of: github, gitlab." required: false run: exec: | @@ -344,86 +347,98 @@ run: echo "Error: ENV0_PR_SOURCE_REPOSITORY environment variable is not set but post_comment=true" exit 1 fi - - # Detect if this is a GitLab repository - if echo "${ENV0_PR_SOURCE_REPOSITORY}" | grep -q "gitlab"; then - # GitLab merge request - if [ -z "${GITLAB_TOKEN}" ]; then - echo "Error: GITLAB_TOKEN environment variable is not set but repository appears to be GitLab" - exit 1 - fi - - # Extract GitLab base URL and project path from repository string - # ENV0_PR_SOURCE_REPOSITORY format: "group/project" or "https://gitlab.com/group/project" or "gitlab.com/group/project" - REPO_STR="${ENV0_PR_SOURCE_REPOSITORY}" - - # Remove protocol if present - REPO_STR=$(echo "${REPO_STR}" | sed 's|^https\?://||') - - # Extract host (default to gitlab.com if not specified) - if echo "${REPO_STR}" | grep -q "/"; then - GITLAB_HOST=$(echo "${REPO_STR}" | cut -d'/' -f1) - PROJECT_PATH=$(echo "${REPO_STR}" | cut -d'/' -f2-) - else - # If no host, assume gitlab.com - GITLAB_HOST="gitlab.com" - PROJECT_PATH="${REPO_STR}" - fi - - # Ensure we have https:// prefix for API calls - if [ "${GITLAB_HOST}" != "gitlab.com" ] && ! echo "${GITLAB_HOST}" | grep -q "^https\?://"; then - GITLAB_BASE_URL="https://${GITLAB_HOST}" - elif [ "${GITLAB_HOST}" = "gitlab.com" ]; then - GITLAB_BASE_URL="https://gitlab.com" - else - GITLAB_BASE_URL="${GITLAB_HOST}" - fi - - # URL encode the project path (handle spaces and special chars) - PROJECT_PATH_ENCODED=$(echo "${PROJECT_PATH}" | sed 's|/|%2F|g' | sed 's| |%20|g') - - MR_IID="${ENV0_PR_NUMBER}" - API_URL="${GITLAB_BASE_URL}/api/v4/projects/${PROJECT_PATH_ENCODED}/merge_requests/${MR_IID}/notes" - - echo "Posting simulation results to GitLab MR ${PROJECT_PATH}!${MR_IID}..." - - # Create JSON payload file using jq - JSON_PAYLOAD_FILE=$(mktemp) - jq -n --rawfile body "${MARKDOWN_FILE}" '{body: $body}' > "${JSON_PAYLOAD_FILE}" - - # Post comment using curl - HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \ - -H "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \ - -H "Content-Type: application/json" \ - --data-binary "@${JSON_PAYLOAD_FILE}" \ - "${API_URL}") - - # Clean up JSON payload file - rm -f "${JSON_PAYLOAD_FILE}" - - if [ "${HTTP_CODE}" -ge 200 ] && [ "${HTTP_CODE}" -lt 300 ]; then - echo "✓ Simulation results posted to GitLab MR" - else - echo "Error: Failed to post comment to GitLab MR (HTTP ${HTTP_CODE})" - exit 1 - fi - else - # GitHub pull request - if [ -z "${GH_BINARY}" ] || [ ! -x "${GH_BINARY}" ]; then - echo "Error: GitHub CLI was not installed correctly" - exit 1 - fi - - if ! "${GH_BINARY}" auth status >/dev/null 2>&1; then - echo "Warning: GitHub CLI authentication not detected. Ensure GH_TOKEN is configured." - fi - - echo "Posting simulation results to ${ENV0_PR_SOURCE_REPOSITORY}#${ENV0_PR_NUMBER}..." - "${GH_BINARY}" pr comment "${ENV0_PR_NUMBER}" \ - --repo "${ENV0_PR_SOURCE_REPOSITORY}" \ - --body-file "${MARKDOWN_FILE}" - echo "✓ Simulation results posted to GitHub PR" + + comment_provider=$(echo "${inputs.comment_provider}" | tr '[:upper:]' '[:lower:]') + if [ -z "${comment_provider}" ]; then + echo "Error: comment_provider input must be set to 'github' or 'gitlab' when post_comment=true" + exit 1 fi + + case "${comment_provider}" in + gitlab) + # GitLab merge request + if [ -z "${GITLAB_TOKEN}" ]; then + echo "Error: GITLAB_TOKEN environment variable is not set but comment_provider=gitlab" + exit 1 + fi + + # Extract GitLab base URL and project path from repository string + # ENV0_PR_SOURCE_REPOSITORY format: "group/project" or "https://gitlab.com/group/project" or "gitlab.com/group/project" + REPO_STR="${ENV0_PR_SOURCE_REPOSITORY}" + + # Remove protocol if present + REPO_STR=$(echo "${REPO_STR}" | sed 's|^https\?://||') + + # Extract host (default to gitlab.com if not specified) + if echo "${REPO_STR}" | grep -q "/"; then + GITLAB_HOST=$(echo "${REPO_STR}" | cut -d'/' -f1) + PROJECT_PATH=$(echo "${REPO_STR}" | cut -d'/' -f2-) + else + # If no host, assume gitlab.com + GITLAB_HOST="gitlab.com" + PROJECT_PATH="${REPO_STR}" + fi + + # Ensure we have https:// prefix for API calls + if [ "${GITLAB_HOST}" != "gitlab.com" ] && ! echo "${GITLAB_HOST}" | grep -q "^https\?://"; then + GITLAB_BASE_URL="https://${GITLAB_HOST}" + elif [ "${GITLAB_HOST}" = "gitlab.com" ]; then + GITLAB_BASE_URL="https://gitlab.com" + else + GITLAB_BASE_URL="${GITLAB_HOST}" + fi + + # URL encode the project path (handle spaces and special chars) + PROJECT_PATH_ENCODED=$(echo "${PROJECT_PATH}" | sed 's|/|%2F|g' | sed 's| |%20|g') + + MR_IID="${ENV0_PR_NUMBER}" + API_URL="${GITLAB_BASE_URL}/api/v4/projects/${PROJECT_PATH_ENCODED}/merge_requests/${MR_IID}/notes" + + echo "Posting simulation results to GitLab MR ${PROJECT_PATH}!${MR_IID}..." + + # Create JSON payload file using jq + JSON_PAYLOAD_FILE=$(mktemp) + jq -n --rawfile body "${MARKDOWN_FILE}" '{body: $body}' > "${JSON_PAYLOAD_FILE}" + + # Post comment using curl + HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \ + -H "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \ + -H "Content-Type: application/json" \ + --data-binary "@${JSON_PAYLOAD_FILE}" \ + "${API_URL}") + + # Clean up JSON payload file + rm -f "${JSON_PAYLOAD_FILE}" + + if [ "${HTTP_CODE}" -ge 200 ] && [ "${HTTP_CODE}" -lt 300 ]; then + echo "✓ Simulation results posted to GitLab MR" + else + echo "Error: Failed to post comment to GitLab MR (HTTP ${HTTP_CODE})" + exit 1 + fi + ;; + github) + # GitHub pull request + if [ -z "${GH_BINARY}" ] || [ ! -x "${GH_BINARY}" ]; then + echo "Error: GitHub CLI was not installed correctly" + exit 1 + fi + + if ! "${GH_BINARY}" auth status >/dev/null 2>&1; then + echo "Warning: GitHub CLI authentication not detected. Ensure GH_TOKEN is configured." + fi + + echo "Posting simulation results to ${ENV0_PR_SOURCE_REPOSITORY}#${ENV0_PR_NUMBER}..." + "${GH_BINARY}" pr comment "${ENV0_PR_NUMBER}" \ + --repo "${ENV0_PR_SOURCE_REPOSITORY}" \ + --body-file "${MARKDOWN_FILE}" + echo "✓ Simulation results posted to GitHub PR" + ;; + *) + echo "Error: comment_provider input must be 'github' or 'gitlab' when post_comment=true" + exit 1 + ;; + esac else if [ -n "${ENV0_PR_NUMBER}" ]; then echo "Skipping comment because post_comment=false."