ikkz 297b07190f
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>
2026-05-09 17:00:43 -05:00
..

display_name description icon verified tags
Git Clone Clone a Git repository by URL and skip if it exists. ../../../../.icons/git.svg true
git
helper

Git Clone

This module allows you to automatically clone a repository by URL and skip if it exists in the base directory provided.

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"
}

Examples

Custom Path

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"
  base_dir = "~/projects/coder"
}

Git Authentication

To use with Git Authentication, add the provider by ID to your template:

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"
}


data "coder_external_auth" "github" {
  id = "github"
}

GitHub clone with branch name

To GitHub clone with a specific branch like feat/example

# Prompt the user for the git repo URL
data "coder_parameter" "git_repo" {
  name         = "git_repo"
  display_name = "Git repository"
  default      = "https://github.com/coder/coder/tree/feat/example"
}

# Clone the repository for branch `feat/example`
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      = data.coder_parameter.git_repo.value
}


# Create a code-server instance for the cloned repository
module "code-server" {
  count    = data.coder_workspace.me.start_count
  source   = "registry.coder.com/coder/code-server/coder"
  version  = "1.2.2"
  agent_id = coder_agent.example.id
  order    = 1
  folder   = "/home/${local.username}/${module.git_clone[count.index].folder_name}"
}

# Create a Coder app for the website
resource "coder_app" "website" {
  count        = data.coder_workspace.me.start_count
  agent_id     = coder_agent.example.id
  order        = 2
  slug         = "website"
  external     = true
  display_name = module.git_clone[count.index].folder_name
  url          = module.git_clone[count.index].web_url
  icon         = module.git_clone[count.index].git_provider != "" ? "/icon/${module.git_clone[count.index].git_provider}.svg" : "/icon/git.svg"
}

Configuring git-clone for a self-hosted GitHub Enterprise Server running at github.example.com

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.example.com/coder/coder/tree/feat/example"
  git_providers = {
    "https://github.example.com/" = {
      provider = "github"
    }

  }
}

GitLab clone with branch name

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.3.0"
  agent_id = coder_agent.example.id
  url      = "https://gitlab.com/coder/coder/-/tree/feat/example"
}

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.3.0"
  agent_id = coder_agent.example.id
  url      = "https://gitlab.example.com/coder/coder/-/tree/feat/example"
  git_providers = {
    "https://gitlab.example.com/" = {
      provider = "gitlab"
    }

  }
}

Git clone with branch_name set

Alternatively, you can set the branch_name attribute to clone a specific branch.

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.3.0"
  agent_id    = coder_agent.example.id
  url         = "https://github.com/coder/coder"
  branch_name = "feat/example"
}

Git clone with different destination folder

By default, the repository will be cloned into a folder matching the repository name. You can use the folder_name attribute to change the name of the destination folder to something else.

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.3.0"
  agent_id    = coder_agent.example.id
  url         = "https://github.com/coder/coder"
  folder_name = "coder-dev"
  base_dir    = "~/projects/coder"
}

Git shallow clone

Limit the clone history to speed-up workspace startup by setting depth.

When depth is greater than 0 the module runs git clone --depth <depth>. 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.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.

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. This is useful for running initialization tasks like installing dependencies or setting up the environment.

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"
  post_clone_script = <<-EOT
    #!/bin/bash
    echo "Repository cloned successfully!"
    # Install dependencies
    npm install
    # Run any other initialization tasks
    make setup
  EOT
}