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>
This commit is contained in:
parent
bce0897099
commit
3e935329a1
@ -14,7 +14,7 @@ This module allows you to automatically clone a repository by URL and skip if it
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://github.com/coder/coder"
|
||||
}
|
||||
@ -28,7 +28,7 @@ module "git-clone" {
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://github.com/coder/coder"
|
||||
base_dir = "~/projects/coder"
|
||||
@ -43,7 +43,7 @@ To use with [Git Authentication](https://coder.com/docs/v2/latest/admin/git-prov
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://github.com/coder/coder"
|
||||
}
|
||||
@ -70,7 +70,7 @@ data "coder_parameter" "git_repo" {
|
||||
module "git_clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.example.id
|
||||
url = data.coder_parameter.git_repo.value
|
||||
}
|
||||
@ -105,7 +105,7 @@ Configuring `git-clone` for a self-hosted GitHub Enterprise Server running at `g
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://github.example.com/coder/coder/tree/feat/example"
|
||||
git_providers = {
|
||||
@ -125,7 +125,7 @@ To GitLab clone with a specific branch like `feat/example`
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://gitlab.com/coder/coder/-/tree/feat/example"
|
||||
}
|
||||
@ -137,7 +137,7 @@ Configuring `git-clone` for a self-hosted GitLab running at `gitlab.example.com`
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://gitlab.example.com/coder/coder/-/tree/feat/example"
|
||||
git_providers = {
|
||||
@ -159,7 +159,7 @@ For example, to clone the `feat/example` branch:
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://github.com/coder/coder"
|
||||
branch_name = "feat/example"
|
||||
@ -177,7 +177,7 @@ For example, this will clone into the `~/projects/coder/coder-dev` folder:
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://github.com/coder/coder"
|
||||
folder_name = "coder-dev"
|
||||
@ -196,13 +196,36 @@ If not defined, the default, `0`, performs a full clone.
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://github.com/coder/coder"
|
||||
depth = 1
|
||||
}
|
||||
```
|
||||
|
||||
## Pre-clone script
|
||||
|
||||
Run a custom script before cloning the repository by setting the `pre_clone_script` variable.
|
||||
This is useful for preparing the environment or validating prerequisites before cloning.
|
||||
|
||||
```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 = "https://github.com/coder/coder"
|
||||
pre_clone_script = <<-EOT
|
||||
#!/bin/bash
|
||||
echo "Preparing to clone repository..."
|
||||
# Check prerequisites
|
||||
command -v npm >/dev/null 2>&1 || { echo "npm is required but not installed."; exit 1; }
|
||||
# Set up environment
|
||||
export NODE_ENV=development
|
||||
EOT
|
||||
}
|
||||
```
|
||||
|
||||
## Post-clone script
|
||||
|
||||
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
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://github.com/coder/coder"
|
||||
post_clone_script = <<-EOT
|
||||
|
||||
@ -261,4 +261,16 @@ describe("git-clone", async () => {
|
||||
expect(output.stdout).toContain("Running post-clone script...");
|
||||
expect(output.stdout).toContain("Post-clone script executed");
|
||||
});
|
||||
|
||||
it("runs pre-clone script", async () => {
|
||||
const state = await runTerraformApply(import.meta.dir, {
|
||||
agent_id: "foo",
|
||||
url: "fake-url",
|
||||
pre_clone_script: "echo 'Pre-clone script executed'",
|
||||
});
|
||||
const output = await executeScriptInContainer(state, "alpine/git");
|
||||
expect(output.stdout).toContain("Running pre-clone script...");
|
||||
expect(output.stdout).toContain("Pre-clone script executed");
|
||||
expect(output.stdout).toContain("Cloning fake-url to ~/fake-url...");
|
||||
});
|
||||
});
|
||||
|
||||
@ -68,6 +68,12 @@ variable "post_clone_script" {
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "pre_clone_script" {
|
||||
description = "Custom script to run before cloning the repository. Runs before git clone, even if the repository already exists."
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
locals {
|
||||
# Remove query parameters and fragments from the URL
|
||||
url = replace(replace(var.url, "/\\?.*/", ""), "/#.*/", "")
|
||||
@ -89,6 +95,8 @@ locals {
|
||||
web_url = startswith(local.clone_url, "git@") ? replace(replace(local.clone_url, ":", "/"), "git@", "https://") : local.clone_url
|
||||
# Encode the post_clone_script for passing to the shell script
|
||||
encoded_post_clone_script = var.post_clone_script != null ? base64encode(var.post_clone_script) : ""
|
||||
# Encode the pre_clone_script for passing to the shell script
|
||||
encoded_pre_clone_script = var.pre_clone_script != null ? base64encode(var.pre_clone_script) : ""
|
||||
}
|
||||
|
||||
output "repo_dir" {
|
||||
@ -129,6 +137,7 @@ resource "coder_script" "git_clone" {
|
||||
BRANCH_NAME : local.branch_name,
|
||||
DEPTH = var.depth,
|
||||
POST_CLONE_SCRIPT : local.encoded_post_clone_script,
|
||||
PRE_CLONE_SCRIPT : local.encoded_pre_clone_script,
|
||||
})
|
||||
display_name = "Git Clone"
|
||||
icon = "/icon/git.svg"
|
||||
|
||||
@ -7,6 +7,7 @@ BRANCH_NAME="${BRANCH_NAME}"
|
||||
CLONE_PATH="$${CLONE_PATH/#\~/$${HOME}}"
|
||||
DEPTH="${DEPTH}"
|
||||
POST_CLONE_SCRIPT="${POST_CLONE_SCRIPT}"
|
||||
PRE_CLONE_SCRIPT="${PRE_CLONE_SCRIPT}"
|
||||
|
||||
# Check if the variable is empty...
|
||||
if [ -z "$REPO_URL" ]; then
|
||||
@ -33,6 +34,16 @@ if [ ! -d "$CLONE_PATH" ]; then
|
||||
mkdir -p "$CLONE_PATH"
|
||||
fi
|
||||
|
||||
# Run pre-clone script if provided
|
||||
if [ -n "$PRE_CLONE_SCRIPT" ]; then
|
||||
echo "Running pre-clone script..."
|
||||
PRE_CLONE_TMP=$(mktemp)
|
||||
echo "$PRE_CLONE_SCRIPT" | base64 -d > "$PRE_CLONE_TMP"
|
||||
chmod +x "$PRE_CLONE_TMP"
|
||||
$PRE_CLONE_TMP
|
||||
rm "$PRE_CLONE_TMP"
|
||||
fi
|
||||
|
||||
# Check if the directory is empty
|
||||
# and if it is, clone the repo, otherwise skip cloning
|
||||
if [ -z "$(ls -A "$CLONE_PATH")" ]; then
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user