0
Git repo test read write
One script reply has been approved by the moderators Verified

This script will test the connection to the Git repo passed stored in the resources passed as an argument. It first clones the repo (checking read) and then attemps an empty push (checking write)

Created by hugo697 404 days ago Viewed 18033 times
0
Submitted by rubenfiszel Bun
Verified 128 days ago
1
import * as wmill from "windmill-client";
2
import { basename } from "node:path"
3
const util = require('util');
4
const exec = util.promisify(require('child_process').exec);
5

6

7
export async function main(repo_url_resource_path: string) {
8
  const cwd = process.cwd();
9
  process.env["HOME"] = ".";
10
  console.log(`Cloning repo from resource`);
11
  const repo_name = await git_clone(repo_url_resource_path);
12
  process.chdir(`${cwd}/${repo_name}`);
13
  console.log(`Attempting an empty push to repository ${repo_name}`);
14
  await git_push();
15
  console.log("Finished");
16
  process.chdir(`${cwd}`);
17
}
18

19
async function git_clone(repo_resource_path: string): Promise<string> {
20
  // TODO: handle private SSH keys as well
21
  let repo_url = (await wmill.getResource(repo_resource_path)).url;
22
  const azureMatch = repo_url.match(/AZURE_DEVOPS_TOKEN\((?<url>.+)\)/);
23
  if (azureMatch) {
24
    console.log(
25
      "Requires Azure DevOps service account access token, requesting..."
26
    );
27
    const azureResource = await wmill.getResource(azureMatch.groups.url);
28
    const response = await fetch(
29
      `https://login.microsoftonline.com/${azureResource.azureTenantId}/oauth2/token`,
30
      {
31
        method: "POST",
32
        body: new URLSearchParams({
33
          client_id: azureResource.azureClientId,
34
          client_secret: azureResource.azureClientSecret,
35
          grant_type: "client_credentials",
36
          resource: "499b84ac-1321-427f-aa17-267ca6975798/.default",
37
        }),
38
      }
39
    );
40
    const { access_token } = await response.json();
41
    repo_url = repo_url.replace(azureMatch[0], access_token);
42
  }
43
  const repo_name = basename(repo_url, ".git");
44
  await sh_run(4, "git", "clone", "--quiet", "--depth", "1", repo_url, repo_name);
45
  return repo_name;
46
}
47
async function git_push() {
48
  await sh_run(undefined, "git", "config", "user.email", process.env["WM_EMAIL"])
49
  await sh_run(undefined, "git", "config", "user.name", process.env["WM_USERNAME"])
50
  await sh_run(undefined, "git", "push");
51
}
52

53
async function sh_run(
54
  secret_position: number | undefined,
55
  cmd: string,
56
  ...args: string[]
57
) {
58
  const nargs = secret_position != undefined ? args.slice() : args;
59
  if (secret_position && secret_position < 0) {
60
    secret_position = nargs.length - 1 + secret_position;
61
  }
62
  let secret: string | undefined = undefined;
63
  if (secret_position != undefined) {
64
    nargs[secret_position] = "***";
65
    secret = args[secret_position];
66
  }
67
  
68
  console.log(`Running '${cmd} ${nargs.join(" ")} ...'`);
69
  const command = exec(`${cmd} ${args.join(" ")}`)
70
  try {
71
    const { stdout, stderr } = await command
72
    if (stdout.length > 0) {
73
      console.log(stdout);
74
    }
75
    if (stderr.length > 0) {
76
      console.log(stderr);
77
    }
78
    console.log("Command successfully executed");
79

80
  } catch(error) {
81
    let errorString = error.toString();
82
    if (secret) {
83
      errorString = errorString.replace(secret, "***");
84
    }
85
    const err = `SH command '${cmd} ${nargs.join(
86
      " "
87
    )}' returned with error ${errorString}`;
88
    throw Error(err);
89
  }
90
}
Other submissions