blinkagent[bot] ab6799ac07
fix(git-clone): use unique temp file for post_clone_script to avoid race condition (#601)
## Summary

Fixes a race condition when multiple `git-clone` modules with
`post_clone_script` run concurrently.

## Problem

All instances of the git-clone module use the same hardcoded
`/tmp/post_clone.sh` path. When multiple modules run concurrently (or
overlap), they collide on the same temp file, causing:

```
rm: cannot remove '/tmp/post_clone.sh': No such file or directory
```

This results in a non-zero exit code, causing the workspace to appear
unhealthy.

## Solution

Use `mktemp` to generate a unique temporary filename for each module
instance:

```bash
POST_CLONE_TMP=$(mktemp /tmp/post_clone_XXXXXX.sh)
```

This ensures each concurrent execution uses its own temp file,
eliminating the race condition.

Fixes #600

---------

Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com>
Co-authored-by: Matyas Danter <mdanter@gmail.com>
2025-12-15 11:19:11 -06: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.2.3"
  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.2.3"
  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.2.3"
  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.2.3"
  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.2.3"
  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.2.3"
  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.2.3"
  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.2.3"
  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.2.3"
  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.2.3"
  agent_id = coder_agent.example.id
  url      = "https://github.com/coder/coder"
  depth    = 1
}

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