Skip to content

Commit 297b071

Browse files
feat(git-clone): add pre_clone_script parameter (#887)
## Summary Add `pre_clone_script` parameter to the git-clone module, allowing users to run custom scripts before cloning a repository. ## Use Case This solves SSH host key verification issues (e.g., "Host key verification failed") by enabling users to configure SSH settings before the clone operation, such as adding known hosts or setting `StrictHostKeyChecking no`. ```tf module "git-clone" { count = data.coder_workspace.me.start_count source = "registry.coder.com/coder/git-clone/coder" version = "1.3.0" agent_id = coder_agent.example.id url = "git@github.com:org/repo.git" pre_clone_script = <<-EOT #!/bin/bash mkdir -p ~/.ssh echo -e "Host github.com\n StrictHostKeyChecking no\n" > ~/.ssh/config chmod 600 ~/.ssh/config EOT } ``` Ref: https://discord.com/channels/747933592273027093/1447777180695396452/1447777180695396452 ## Type of Change - [ ] New module - [ ] New template - [ ] Bug fix - [x] Feature/enhancement - [ ] Documentation - [ ] Other ## Module Information **Path:** `registry/coder/modules/git-clone` **New version:** `v1.3.0` **Breaking change:** [ ] Yes [x] No ## Testing & Validation - [x] Tests pass (`bun test`) - [x] Code formatted (`bun fmt`) - [x] Changes tested locally Co-authored-by: DevCats <christofer@coder.com>
1 parent bce0897 commit 297b071

4 files changed

Lines changed: 66 additions & 11 deletions

File tree

registry/coder/modules/git-clone/README.md

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ This module allows you to automatically clone a repository by URL and skip if it
1414
module "git-clone" {
1515
count = data.coder_workspace.me.start_count
1616
source = "registry.coder.com/coder/git-clone/coder"
17-
version = "1.2.3"
17+
version = "1.3.0"
1818
agent_id = coder_agent.example.id
1919
url = "https://github.com/coder/coder"
2020
}
@@ -28,7 +28,7 @@ module "git-clone" {
2828
module "git-clone" {
2929
count = data.coder_workspace.me.start_count
3030
source = "registry.coder.com/coder/git-clone/coder"
31-
version = "1.2.3"
31+
version = "1.3.0"
3232
agent_id = coder_agent.example.id
3333
url = "https://github.com/coder/coder"
3434
base_dir = "~/projects/coder"
@@ -43,7 +43,7 @@ To use with [Git Authentication](https://coder.com/docs/v2/latest/admin/git-prov
4343
module "git-clone" {
4444
count = data.coder_workspace.me.start_count
4545
source = "registry.coder.com/coder/git-clone/coder"
46-
version = "1.2.3"
46+
version = "1.3.0"
4747
agent_id = coder_agent.example.id
4848
url = "https://github.com/coder/coder"
4949
}
@@ -70,7 +70,7 @@ data "coder_parameter" "git_repo" {
7070
module "git_clone" {
7171
count = data.coder_workspace.me.start_count
7272
source = "registry.coder.com/coder/git-clone/coder"
73-
version = "1.2.3"
73+
version = "1.3.0"
7474
agent_id = coder_agent.example.id
7575
url = data.coder_parameter.git_repo.value
7676
}
@@ -105,7 +105,7 @@ Configuring `git-clone` for a self-hosted GitHub Enterprise Server running at `g
105105
module "git-clone" {
106106
count = data.coder_workspace.me.start_count
107107
source = "registry.coder.com/coder/git-clone/coder"
108-
version = "1.2.3"
108+
version = "1.3.0"
109109
agent_id = coder_agent.example.id
110110
url = "https://github.example.com/coder/coder/tree/feat/example"
111111
git_providers = {
@@ -125,7 +125,7 @@ To GitLab clone with a specific branch like `feat/example`
125125
module "git-clone" {
126126
count = data.coder_workspace.me.start_count
127127
source = "registry.coder.com/coder/git-clone/coder"
128-
version = "1.2.3"
128+
version = "1.3.0"
129129
agent_id = coder_agent.example.id
130130
url = "https://gitlab.com/coder/coder/-/tree/feat/example"
131131
}
@@ -137,7 +137,7 @@ Configuring `git-clone` for a self-hosted GitLab running at `gitlab.example.com`
137137
module "git-clone" {
138138
count = data.coder_workspace.me.start_count
139139
source = "registry.coder.com/coder/git-clone/coder"
140-
version = "1.2.3"
140+
version = "1.3.0"
141141
agent_id = coder_agent.example.id
142142
url = "https://gitlab.example.com/coder/coder/-/tree/feat/example"
143143
git_providers = {
@@ -159,7 +159,7 @@ For example, to clone the `feat/example` branch:
159159
module "git-clone" {
160160
count = data.coder_workspace.me.start_count
161161
source = "registry.coder.com/coder/git-clone/coder"
162-
version = "1.2.3"
162+
version = "1.3.0"
163163
agent_id = coder_agent.example.id
164164
url = "https://github.com/coder/coder"
165165
branch_name = "feat/example"
@@ -177,7 +177,7 @@ For example, this will clone into the `~/projects/coder/coder-dev` folder:
177177
module "git-clone" {
178178
count = data.coder_workspace.me.start_count
179179
source = "registry.coder.com/coder/git-clone/coder"
180-
version = "1.2.3"
180+
version = "1.3.0"
181181
agent_id = coder_agent.example.id
182182
url = "https://github.com/coder/coder"
183183
folder_name = "coder-dev"
@@ -196,13 +196,36 @@ If not defined, the default, `0`, performs a full clone.
196196
module "git-clone" {
197197
count = data.coder_workspace.me.start_count
198198
source = "registry.coder.com/coder/git-clone/coder"
199-
version = "1.2.3"
199+
version = "1.3.0"
200200
agent_id = coder_agent.example.id
201201
url = "https://github.com/coder/coder"
202202
depth = 1
203203
}
204204
```
205205

206+
## Pre-clone script
207+
208+
Run a custom script before cloning the repository by setting the `pre_clone_script` variable.
209+
This is useful for preparing the environment or validating prerequisites before cloning.
210+
211+
```tf
212+
module "git-clone" {
213+
count = data.coder_workspace.me.start_count
214+
source = "registry.coder.com/coder/git-clone/coder"
215+
version = "1.3.0"
216+
agent_id = coder_agent.example.id
217+
url = "https://github.com/coder/coder"
218+
pre_clone_script = <<-EOT
219+
#!/bin/bash
220+
echo "Preparing to clone repository..."
221+
# Check prerequisites
222+
command -v npm >/dev/null 2>&1 || { echo "npm is required but not installed."; exit 1; }
223+
# Set up environment
224+
export NODE_ENV=development
225+
EOT
226+
}
227+
```
228+
206229
## Post-clone script
207230

208231
Run a custom script after cloning the repository by setting the `post_clone_script` variable.
@@ -212,7 +235,7 @@ This is useful for running initialization tasks like installing dependencies or
212235
module "git-clone" {
213236
count = data.coder_workspace.me.start_count
214237
source = "registry.coder.com/coder/git-clone/coder"
215-
version = "1.2.3"
238+
version = "1.3.0"
216239
agent_id = coder_agent.example.id
217240
url = "https://github.com/coder/coder"
218241
post_clone_script = <<-EOT

registry/coder/modules/git-clone/main.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,4 +261,16 @@ describe("git-clone", async () => {
261261
expect(output.stdout).toContain("Running post-clone script...");
262262
expect(output.stdout).toContain("Post-clone script executed");
263263
});
264+
265+
it("runs pre-clone script", async () => {
266+
const state = await runTerraformApply(import.meta.dir, {
267+
agent_id: "foo",
268+
url: "fake-url",
269+
pre_clone_script: "echo 'Pre-clone script executed'",
270+
});
271+
const output = await executeScriptInContainer(state, "alpine/git");
272+
expect(output.stdout).toContain("Running pre-clone script...");
273+
expect(output.stdout).toContain("Pre-clone script executed");
274+
expect(output.stdout).toContain("Cloning fake-url to ~/fake-url...");
275+
});
264276
});

registry/coder/modules/git-clone/main.tf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ variable "post_clone_script" {
6868
default = null
6969
}
7070

71+
variable "pre_clone_script" {
72+
description = "Custom script to run before cloning the repository. Runs before git clone, even if the repository already exists."
73+
type = string
74+
default = null
75+
}
76+
7177
locals {
7278
# Remove query parameters and fragments from the URL
7379
url = replace(replace(var.url, "/\\?.*/", ""), "/#.*/", "")
@@ -89,6 +95,8 @@ locals {
8995
web_url = startswith(local.clone_url, "git@") ? replace(replace(local.clone_url, ":", "/"), "git@", "https://") : local.clone_url
9096
# Encode the post_clone_script for passing to the shell script
9197
encoded_post_clone_script = var.post_clone_script != null ? base64encode(var.post_clone_script) : ""
98+
# Encode the pre_clone_script for passing to the shell script
99+
encoded_pre_clone_script = var.pre_clone_script != null ? base64encode(var.pre_clone_script) : ""
92100
}
93101

94102
output "repo_dir" {
@@ -129,6 +137,7 @@ resource "coder_script" "git_clone" {
129137
BRANCH_NAME : local.branch_name,
130138
DEPTH = var.depth,
131139
POST_CLONE_SCRIPT : local.encoded_post_clone_script,
140+
PRE_CLONE_SCRIPT : local.encoded_pre_clone_script,
132141
})
133142
display_name = "Git Clone"
134143
icon = "/icon/git.svg"

registry/coder/modules/git-clone/run.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ BRANCH_NAME="${BRANCH_NAME}"
77
CLONE_PATH="$${CLONE_PATH/#\~/$${HOME}}"
88
DEPTH="${DEPTH}"
99
POST_CLONE_SCRIPT="${POST_CLONE_SCRIPT}"
10+
PRE_CLONE_SCRIPT="${PRE_CLONE_SCRIPT}"
1011

1112
# Check if the variable is empty...
1213
if [ -z "$REPO_URL" ]; then
@@ -33,6 +34,16 @@ if [ ! -d "$CLONE_PATH" ]; then
3334
mkdir -p "$CLONE_PATH"
3435
fi
3536

37+
# Run pre-clone script if provided
38+
if [ -n "$PRE_CLONE_SCRIPT" ]; then
39+
echo "Running pre-clone script..."
40+
PRE_CLONE_TMP=$(mktemp)
41+
echo "$PRE_CLONE_SCRIPT" | base64 -d > "$PRE_CLONE_TMP"
42+
chmod +x "$PRE_CLONE_TMP"
43+
$PRE_CLONE_TMP
44+
rm "$PRE_CLONE_TMP"
45+
fi
46+
3647
# Check if the directory is empty
3748
# and if it is, clone the repo, otherwise skip cloning
3849
if [ -z "$(ls -A "$CLONE_PATH")" ]; then

0 commit comments

Comments
 (0)