Skip to content
DocsAll docs
Console

Code in a job

Clone a GitHub or GitLab repository in a job with plain git, through the git credential helper and a connector of the owner.

Last updated

On this page

Description and operation

General

A pipeline has no repository of its own. A job gets code the same way that you do: a step runs git clone. A job that asks for permissions.git: read gets a short-lived, read-only credential for GitHub and GitLab. Kloudlite does not record which repositories a job reads. This page holds every rule about code in a job.

To do these tasks with an AI agent, see Agentic workflows – General.

How it works

Each time git needs a credential for an HTTPS remote, it runs the Kloudlite git credential helper. The helper sends the host and the path of the repository to Kloudlite. Kloudlite makes a read-only credential from a connector of the pipeline owner, and git uses it for that one command.

  1. The job asks for git access with "permissions": { "git": "read" }.

  2. A step runs git clone https://github.com/acme/payments, or git fetch in a clone.

  3. The step starts in the home directory, so the files are in ~/payments. A later step reads them with "cwd": "payments".

A job without git: read gets no credential. A public repository needs no credential, so a job clones it without git: read.

What a credential reads

HostConnector that answersCredentialLife
github.comThe GitHub connector whose account is the first part of the path, acme in acme/payments.A token with read access to the contents of every repository that the GitHub App is installed on.1 hour.
gitlab.comThe GitLab connector that picked the project. See GitLab.A read-only deploy token on that one project.1 hour at most, or until the job token ends if that is earlier.

A pipeline of a team uses the connectors of the team. It never uses the connector of a member. A personal pipeline uses your own connectors.

WARNING

A job with git: read can read every repository that the GitHub App is installed on, a webhook run included. The caller of a webhook controls webhook.body. Do not clone a URL that comes from webhook.body. Install the app only on the repositories that pipelines need.

Rules

  • HTTPS only. A [email protected]: or ssh:// URL gets no credential.
  • Read only. A git push with the credential fails.
  • Only github.com and gitlab.com. For another host, see Other git hosts.
  • A URL that holds a user name, such as https://[email protected]/acme/payments, gets no credential. Git uses the credential of the URL.
  • A credential is given only while that job is running. A request after the job or the run ends gets none. A credential that was already given keeps working until it expires, up to 1 hour. Nothing revokes it.
  • A job token makes at most 60 credential requests in one minute. See Limits.
  • The platform sets GIT_CONFIG_COUNT and the GIT_CONFIG_KEY_* and GIT_CONFIG_VALUE_* variables. A job or step env that sets GIT_CONFIG_COUNT replaces the credential helper.
  • The platform sets GIT_TERMINAL_PROMPT=0, so a clone with no credential fails at once and does not wait for a password.

When the helper gets no credential, it writes kl git-credential: and the reason to the log of the step. Git then fails the command.

Git in the job

The helper needs git 2.31 or later. A job with no runtime gets git from the platform. A job with packages must list git. A job with image must use an image that contains git 2.31 or later.

Other git hosts

Kloudlite makes no credential for other hosts, such as Bitbucket or your own GitLab. Use a personal access token of that host instead. Keep the token in a secret, and put it in the clone URL. The user name in the URL depends on the host.

A token that you paste is static. Kloudlite cannot make it read-only or short-lived, so the job can do what the token permits. A log line that holds the token shows *** in its place. Git keeps the URL, and the token in it, in the .git/config of the clone.

Tasks

Clone a repository in a job

Reason for the task: Run the tests or the scripts of a private GitHub or GitLab repository in a job.

Job set-up

Procedure

  1. Add "permissions": { "git": "read" } to the job, and add a git clone step before the steps that use the code.

    json
    {  "name": "payments-tests",  "jobs": {    "test": {      "packages": ["git", "nodejs"],      "permissions": { "git": "read" },      "steps": [        { "name": "clone", "run": "git clone https://github.com/acme/payments" },        { "name": "test", "run": "npm ci && npm test", "cwd": "payments" }      ]    }  }}
  2. Use https://gitlab.com/acme/payments.git as the URL for a GitLab project.

  3. Create the pipeline from the file, and start a run. See Start a run and follow it.

Close-out

  1. Read the log of test. Make sure that the step clone shows Cloning into 'payments' and no kl git-credential: line.
  2. Make sure that the run ends in success.

Choose the branch at the start of a run

Reason for the task: Run the same pipeline on another branch, without a new version.

Job set-up

  • Access: you. For a team, an admin to change the definition, and an active member to start the run.
  • Conditions: you have the definition of task 001.
  • References: Inputs.

Procedure

  1. Add the input branch. Put it in the step env, and read it in the script as "$BRANCH".

    json
    {  "name": "payments-tests",  "inputs": { "branch": { "default": "main" } },  "jobs": {    "test": {      "packages": ["git", "nodejs"],      "permissions": { "git": "read" },      "steps": [        {          "name": "clone",          "run": "git clone --branch \"$BRANCH\" https://github.com/acme/payments",          "env": { "BRANCH": "${{ inputs.branch }}" }        },        { "name": "test", "run": "npm ci && npm test", "cwd": "payments" }      ]    }  }}
  2. Send the definition as the next version. See Save a new version.

  3. Start a run with the branch fix-rounding.

    Python
    run = kl.pipelines.run(owner="acme", pipeline="payments-tests", inputs={"branch": "fix-rounding"})print(run.wait())
    TypeScript
    const run = await kl.pipelines.run({ owner: "acme", pipeline: "payments-tests", inputs: { branch: "fix-rounding" } });console.log(await run.wait());
    Go
    run, err := kl.Pipelines.Run(kloudlite.RunPipeline{Owner: "acme", Pipeline: "payments-tests", Inputs: map[string]string{"branch": "fix-rounding"}})if err != nil {    log.Fatal(err)}state, err := run.Wait(kloudlite.WaitRun{})if err != nil {    log.Fatal(err)}fmt.Println(state)
    Ruby
    run = kl.pipelines.run(owner: "acme", pipeline: "payments-tests", inputs: { "branch" => "fix-rounding" })puts run.wait
    Java
    var run = kl.pipelines().run(new Kloudlite.RunPipeline().owner("acme").pipeline("payments-tests").input("branch", "fix-rounding"));System.out.println(run.waitFor());
    CLI
    RUN=$(kloudlite pipelines run acme/payments-tests --input branch=fix-rounding --json | jq -r .id)kloudlite pipelines wait-run acme payments-tests "$RUN"

Close-out

  1. Read the log of the step clone. Make sure that it cloned the branch fix-rounding.

Clone from another git host

Reason for the task: Get code from a host that Kloudlite makes no credential for, such as Bitbucket or your own GitLab.

Job set-up

  • Access: you. For a team, an admin.
  • Conditions: you have a read-only personal access token of the host.
  • References: Secrets, Other git hosts.
CAUTION

Give the token read access to the repositories that the job needs, and nothing more. The job can do what the token permits.

Procedure

  1. Set the token as the secret GIT_HOST_TOKEN of the owner. See Secrets.

  2. Add the secret to the job, and put it in the clone URL.

    json
    {  "name": "payments-mirror",  "jobs": {    "test": {      "secrets": ["GIT_HOST_TOKEN"],      "steps": [        { "name": "clone", "run": "git clone \"https://oauth2:[email protected]/acme/payments.git\"" }      ]    }  }}
  3. Create the pipeline from the file, and start a run. See Start a run and follow it.

Close-out

  1. Read the log of the step clone. Make sure that it shows Cloning into 'payments' and no token.

Troubleshooting

SymptomPossible causeCorrective action
fatal: could not read Username for 'https://github.com': terminal prompts disabledThe job has no permissions.git: read, or the URL is not on github.com or gitlab.com.Add "permissions": { "git": "read" } to the job. For another host, see task 003.
kl git-credential: no git credential is available hereThe job has no permissions.git: read.Add "permissions": { "git": "read" } to the job.
kl git-credential: no git connector of acme covers github.com/acme/paymentsNo connected connector of the owner has the account acme, or no GitLab connector picked the project.Connect the account, or pick the project. See Connectors.
remote: Repository not found. from github.comThe GitHub App is not installed on that repository.Add the repository to the installation in the settings of the GitHub account.
kl git-credential: path is not a repository pathThe URL has more than owner/name after github.com, or has a character that a repository name cannot have.Use the URL https://github.com/OWNER/NAME.
kl git-credential: too many git credential requests; retry in a minuteThe job made more than 60 git requests in one minute.Clone once, and run later commands in the clone.
kl git-credential: the provider refused the credentialThe GitLab account lost the Maintainer role on the project.Give the account the Maintainer role, or pick the project from an account that has it.
kl git-credential: connector NAME is expiredThe sign-in of the GitLab connector stopped working.Select Reconnect for the connector. See Connectors.
kl git-credential: GitHub is not configuredThis region has no GitHub App set up.Ask a superadmin to set up the GitHub App.
The log of a step shows git: not foundThe job lists packages without git, or its image has no git.Add git to packages, or use an image with git.
fatal: could not read Username with git older than 2.31Git older than 2.31 does not read GIT_CONFIG_COUNT.Use an image with git 2.31 or later.