feat(git-clone module): added post_clone_script. (#357)

Co-authored-by: DevCats <christofer@coder.com>
Co-authored-by: Atif Ali <atif@coder.com>
This commit is contained in:
Riajul Islam
2025-10-15 18:53:17 +06:00
committed by GitHub
parent 63cad25954
commit da5a2ba6a8
4 changed files with 71 additions and 12 deletions
+33 -10
View File
@@ -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.1.2"
version = "1.2.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.1.2"
version = "1.2.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.1.2"
version = "1.2.0"
agent_id = coder_agent.example.id
url = "https://github.com/coder/coder"
}
@@ -69,7 +69,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.1.2"
version = "1.2.0"
agent_id = coder_agent.example.id
url = data.coder_parameter.git_repo.value
}
@@ -103,7 +103,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.1.2"
version = "1.2.0"
agent_id = coder_agent.example.id
url = "https://github.example.com/coder/coder/tree/feat/example"
git_providers = {
@@ -122,7 +122,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.1.2"
version = "1.2.0"
agent_id = coder_agent.example.id
url = "https://gitlab.com/coder/coder/-/tree/feat/example"
}
@@ -134,7 +134,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.1.2"
version = "1.2.0"
agent_id = coder_agent.example.id
url = "https://gitlab.example.com/coder/coder/-/tree/feat/example"
git_providers = {
@@ -155,7 +155,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.1.2"
version = "1.2.0"
agent_id = coder_agent.example.id
url = "https://github.com/coder/coder"
branch_name = "feat/example"
@@ -173,7 +173,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.1.2"
version = "1.2.0"
agent_id = coder_agent.example.id
url = "https://github.com/coder/coder"
folder_name = "coder-dev"
@@ -192,9 +192,32 @@ If not defined, the default, `0`, performs a full clone.
module "git-clone" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/git-clone/coder"
version = "1.1.0"
version = "1.2.0"
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.
```tf
module "git-clone" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/git-clone/coder"
version = "1.2.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
}
```
+18 -1
View File
@@ -30,11 +30,12 @@ describe("git-clone", async () => {
url: "fake-url",
});
const output = await executeScriptInContainer(state, "alpine/git");
expect(output.exitCode).toBe(128);
expect(output.stdout).toEqual([
"Creating directory ~/fake-url...",
"Cloning fake-url to ~/fake-url...",
]);
expect(output.stderr.join(" ")).toContain("fatal");
expect(output.stderr.join(" ")).toContain("fake-url");
});
it("repo_dir should match repo name for https", async () => {
@@ -244,4 +245,20 @@ describe("git-clone", async () => {
"Cloning https://github.com/michaelbrewer/repo-tests.log to ~/repo-tests.log on branch feat/branch...",
]);
});
it("runs post-clone script", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
url: "fake-url",
post_clone_script: "echo 'Post-clone script executed'",
});
const output = await executeScriptInContainer(
state,
"alpine/git",
"sh",
"mkdir -p ~/fake-url && echo 'existing' > ~/fake-url/file.txt",
);
expect(output.stdout).toContain("Running post-clone script...");
expect(output.stdout).toContain("Post-clone script executed");
});
});
+9
View File
@@ -62,6 +62,12 @@ variable "depth" {
default = 0
}
variable "post_clone_script" {
description = "Custom script to run after cloning the repository. Runs always after 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, "/\\?.*/", ""), "/#.*/", "")
@@ -81,6 +87,8 @@ locals {
clone_path = var.base_dir != "" ? join("/", [var.base_dir, local.folder_name]) : join("/", ["~", local.folder_name])
# Construct the web URL
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) : ""
}
output "repo_dir" {
@@ -120,6 +128,7 @@ resource "coder_script" "git_clone" {
REPO_URL : local.clone_url,
BRANCH_NAME : local.branch_name,
DEPTH = var.depth,
POST_CLONE_SCRIPT : local.encoded_post_clone_script,
})
display_name = "Git Clone"
icon = "/icon/git.svg"
+11 -1
View File
@@ -6,6 +6,7 @@ BRANCH_NAME="${BRANCH_NAME}"
# Expand home if it's specified!
CLONE_PATH="$${CLONE_PATH/#\~/$${HOME}}"
DEPTH="${DEPTH}"
POST_CLONE_SCRIPT="${POST_CLONE_SCRIPT}"
# Check if the variable is empty...
if [ -z "$REPO_URL" ]; then
@@ -52,5 +53,14 @@ if [ -z "$(ls -A "$CLONE_PATH")" ]; then
fi
else
echo "$CLONE_PATH already exists and isn't empty, skipping clone!"
exit 0
fi
# Run post-clone script if provided
if [ -n "$POST_CLONE_SCRIPT" ]; then
echo "Running post-clone script..."
echo "$POST_CLONE_SCRIPT" | base64 -d > /tmp/post_clone.sh
chmod +x /tmp/post_clone.sh
cd "$CLONE_PATH"
/tmp/post_clone.sh
rm /tmp/post_clone.sh
fi