diff --git a/.images/git-config-params.png b/.images/git-config-params.png new file mode 100644 index 0000000..55f24a7 Binary files /dev/null and b/.images/git-config-params.png differ diff --git a/git-config/README.md b/git-config/README.md new file mode 100644 index 0000000..1666374 --- /dev/null +++ b/git-config/README.md @@ -0,0 +1,48 @@ +--- +display_name: Git Config +description: Stores Git configuration from Coder credentials +icon: ../.icons/git.svg +maintainer_github: coder +verified: true +tags: [helper, git] +--- + +# git-config + +Runs a script that updates git credentials in the workspace to match the user's Coder credentials, optionally allowing to the developer to override the defaults. + +```hcl +module "git-config" { + source = "https://registry.coder.com/modules/git-config" + agent_id = coder_agent.example.id +} +``` + +TODO: Add screenshot + +## Examples + +### Allow users to override both username and email + +```hcl +module "git-config" { + source = "https://registry.coder.com/modules/git-config" + agent_id = coder_agent.example.id + allow_email_change = true +} +``` + +TODO: Add screenshot + +## Disallowing users from overriding both username and email + +```hcl +module "git-config" { + source = "https://registry.coder.com/modules/git-config" + agent_id = coder_agent.example.id + allow_username_change = false + allow_email_change = false +} +``` + +TODO: Add screenshot diff --git a/git-config/main.test.ts b/git-config/main.test.ts new file mode 100644 index 0000000..6fbdbc5 --- /dev/null +++ b/git-config/main.test.ts @@ -0,0 +1,43 @@ +import { describe, expect, it } from "bun:test"; +import { + executeScriptInContainer, + runTerraformApply, + runTerraformInit, + testRequiredVariables, +} from "../test"; + +describe("git-config", async () => { + await runTerraformInit(import.meta.dir); + + testRequiredVariables(import.meta.dir, { + agent_id: "foo", + }); + + it("fails without git", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "foo", + }); + const output = await executeScriptInContainer(state, "alpine"); + expect(output.exitCode).toBe(1); + expect(output.stdout).toEqual([ + "\u001B[0;1mChecking git-config!", + "Git is not installed!", + ]); + }); + + it("runs with git", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "foo", + }); + const output = await executeScriptInContainer(state, "alpine/git"); + expect(output.exitCode).toBe(0); + expect(output.stdout).toEqual([ + "\u001B[0;1mChecking git-config!", + "git-config: No user.email found, setting to ", + "git-config: No user.name found, setting to default", + "", + "\u001B[0;1mgit-config: using email: ", + "\u001B[0;1mgit-config: using username: default", + ]); + }); +}); diff --git a/git-config/main.tf b/git-config/main.tf new file mode 100644 index 0000000..55d9cca --- /dev/null +++ b/git-config/main.tf @@ -0,0 +1,61 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + coder = { + source = "coder/coder" + version = ">= 0.12" + } + } +} + +variable "agent_id" { + type = string + description = "The ID of a Coder agent." +} + +variable "allow_username_change" { + type = bool + description = "Allow developers to change their git username." + default = true +} + +variable "allow_email_change" { + type = bool + description = "Allow developers to change their git email." + default = false +} + + +data "coder_workspace" "me" {} + +data "coder_parameter" "user_email" { + count = var.allow_email_change ? 1 : 0 + name = "user_email" + type = "string" + default = "" + description = "Git user.email to be used for commits. Leave empty to default to Coder username." + display_name = "Git config user.email" + mutable = true +} + +data "coder_parameter" "username" { + count = var.allow_username_change ? 1 : 0 + name = "username" + type = "string" + default = "" + description = "Git user.name to be used for commits. Leave empty to default to Coder username." + display_name = "Git config user.name" + mutable = true +} + +resource "coder_script" "git_config" { + agent_id = var.agent_id + script = templatefile("${path.module}/run.sh", { + GIT_USERNAME = try(data.coder_parameter.username[0].value, "") == "" ? data.coder_workspace.me.owner : try(data.coder_parameter.username[0].value, "") + GIT_EMAIL = try(data.coder_parameter.user_email[0].value, "") == "" ? data.coder_workspace.me.owner_email : try(data.coder_parameter.user_email[0].value, "") + }) + display_name = "Git Config" + icon = "/icon/git.svg" + run_on_start = true +} diff --git a/git-config/run.sh b/git-config/run.sh new file mode 100644 index 0000000..586be4d --- /dev/null +++ b/git-config/run.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env sh + +BOLD='\033[0;1m' +printf "$${BOLD}Checking git-config!\n" + +# Check if git is installed +command -v git >/dev/null 2>&1 || { + echo "Git is not installed!" + exit 1 +} + +# Set git username and email if missing +if [ -z $(git config --get user.email) ]; then + printf "git-config: No user.email found, setting to ${GIT_EMAIL}\n" + git config --global user.email "${GIT_EMAIL}" +fi + +if [ -z $(git config --get user.name) ]; then + printf "git-config: No user.name found, setting to ${GIT_USERNAME}\n" + git config --global user.name "${GIT_USERNAME}" +fi + +printf "\n$${BOLD}git-config: using email: $(git config --get user.email)\n" +printf "$${BOLD}git-config: using username: $(git config --get user.name)\n\n"