blinkagent[bot] a0a3783a51
docs(dotfiles): add hint about using SSH URLs when HTTPS cloning is restricted (#757)
Some Git providers (e.g. on-prem GitLab) disable HTTPS cloning by
default, which causes the dotfiles clone to silently fail during
workspace startup. Users see "Startup scripts are still running" but the
dotfiles folder is never populated.

This PR adds two small documentation touches:

1. **`main.tf` default description** — appends a one-liner suggesting
SSH URLs when HTTPS is restricted. This is what users see in the Coder
UI parameter prompt.
2. **`README.md`** — new "SSH vs HTTPS URLs" section with an example and
a brief explanation of why SSH URLs are more reliable during startup.

No logic changes, no new variables — just documentation.

---------

Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com>
Co-authored-by: DevCats <christofer@coder.com>
2026-02-27 14:48:55 -06:00

147 lines
4.6 KiB
HCL

terraform {
required_version = ">= 1.0"
required_providers {
coder = {
source = "coder/coder"
version = ">= 2.5"
}
}
}
variable "order" {
type = number
description = "The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order)."
default = null
}
variable "group" {
type = string
description = "The name of a group that this app belongs to."
default = null
}
variable "agent_id" {
type = string
description = "The ID of a Coder agent."
}
variable "description" {
type = string
description = "A custom description for the dotfiles parameter. This is shown in the UI - and allows you to customize the instructions you give to your users."
default = "Enter a URL for a [dotfiles repository](https://dotfiles.github.io) to personalize your workspace. Use an SSH URL (e.g. `git@host:user/repo`) if your Git provider restricts HTTPS cloning."
}
variable "default_dotfiles_uri" {
type = string
description = "The default dotfiles URI if the workspace user does not provide one"
default = ""
validation {
condition = (
var.default_dotfiles_uri == "" ||
can(regex("^(https?://|ssh://|git@|git://)[a-zA-Z0-9._/:@~-]+$", var.default_dotfiles_uri))
)
error_message = "Must be a valid dotfiles repository URL (https, git@, or git://) without special characters."
}
}
variable "dotfiles_uri" {
type = string
description = "The URL to a dotfiles repository. (optional, when set, the user isn't prompted for their dotfiles)"
default = null
validation {
condition = (
var.dotfiles_uri == null ||
var.dotfiles_uri == "" ||
can(regex("^(https?://|ssh://|git@|git://)[a-zA-Z0-9._/:@~-]+$", var.dotfiles_uri))
)
error_message = "Must be a valid dotfiles repository URL (https, git@, or git://) without special characters."
}
}
variable "user" {
type = string
description = "The name of the user to apply the dotfiles to. (optional, applies to the current user by default)"
default = null
validation {
condition = var.user == null || can(regex("^[a-zA-Z_][a-zA-Z0-9_-]*$", var.user))
error_message = "Must be a valid username without special characters."
}
}
variable "coder_parameter_order" {
type = number
description = "The order determines the position of a template parameter in the UI/CLI presentation. The lowest order is shown first and parameters with equal order are sorted by name (ascending order)."
default = null
}
variable "manual_update" {
type = bool
description = "If true, this adds a button to workspace page to refresh dotfiles on demand."
default = false
}
variable "post_clone_script" {
description = "Custom script to run after applying dotfiles. Runs every time, even if dotfiles were already applied."
type = string
default = null
}
data "coder_parameter" "dotfiles_uri" {
count = var.dotfiles_uri == null ? 1 : 0
type = "string"
name = "dotfiles_uri"
display_name = "Dotfiles URL"
order = var.coder_parameter_order
default = var.default_dotfiles_uri
description = var.description
mutable = true
icon = "/icon/dotfiles.svg"
validation {
regex = "^$|^(https?://|ssh://|git@|git://)[a-zA-Z0-9._/:@~-]+$"
error = "Must be a valid dotfiles repository URL (https, git@, or git://) without special characters."
}
}
locals {
dotfiles_uri = var.dotfiles_uri != null ? var.dotfiles_uri : data.coder_parameter.dotfiles_uri[0].value
user = var.user != null ? var.user : ""
encoded_post_clone_script = var.post_clone_script != null ? base64encode(var.post_clone_script) : ""
}
resource "coder_script" "dotfiles" {
agent_id = var.agent_id
script = templatefile("${path.module}/run.sh", {
DOTFILES_URI : local.dotfiles_uri,
DOTFILES_USER : local.user,
POST_CLONE_SCRIPT : local.encoded_post_clone_script
})
display_name = "Dotfiles"
icon = "/icon/dotfiles.svg"
run_on_start = true
}
resource "coder_app" "dotfiles" {
count = var.manual_update ? 1 : 0
agent_id = var.agent_id
display_name = "Refresh Dotfiles"
slug = "dotfiles"
icon = "/icon/dotfiles.svg"
order = var.order
group = var.group
command = templatefile("${path.module}/run.sh", {
DOTFILES_URI : local.dotfiles_uri,
DOTFILES_USER : local.user,
POST_CLONE_SCRIPT : local.encoded_post_clone_script
})
}
output "dotfiles_uri" {
description = "Dotfiles URI"
value = local.dotfiles_uri
}