> ## Documentation Index
> Fetch the complete documentation index at: https://docs.diversion.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# CI/CD

> Configure your CI/CD platform to use diversion

## Generate an API Token

<Steps>
  <Step title="Navigate to the tokens page">
    Click on your avatar and select *Integrations*.

    <img alt="Drop Down Menu" style={{width: '90%', borderRadius: '1.5rem', border: '.3rem solid #555', boxShadow: '0 0 1rem #888' }} src="https://mintcdn.com/diversion-2/cRpeD_gsb0j32D_2/images/nav-integrations.png?fit=max&auto=format&n=cRpeD_gsb0j32D_2&q=85&s=6419b74f02ec862130e64baf07318631" width="209" height="340" data-path="images/nav-integrations.png" />
  </Step>

  <Step title="Generate a new token">
    A new window will open. Click the *Generate a new API token* button.

    <img alt="Generate Token" style={{width: '90%', borderRadius: '1.5rem', border: '.3rem solid #555', boxShadow: '0 0 1rem #888' }} src="https://mintcdn.com/diversion-2/Ro_2EfA8JfapE5By/images/api-tokens-buttons.png?fit=max&auto=format&n=Ro_2EfA8JfapE5By&q=85&s=b9cd0aa22d587c27896cd9b652146675" width="760" height="200" data-path="images/api-tokens-buttons.png" />

    Provide your login credentials, if prompted.
    You'll be redirected to your new API Token.

    <img alt="Generate Token" style={{width: '90%', borderRadius: '1.5rem', border: '.3rem solid #555', boxShadow: '0 0 1rem #888' }} src="https://mintcdn.com/diversion-2/9UNl-chZpzaTgulZ/images/copy-api-token.png?fit=max&auto=format&n=9UNl-chZpzaTgulZ&q=85&s=4580c38eba1d3be27eefaf84c6df230a" width="1547" height="667" data-path="images/copy-api-token.png" />

    Use the *Copy* icon to copy the token and store it in a secure place.
    <Note>This is the only time you'll see the token here and there will be no way to retrieve it later.
    If you lose it, you will have to revoke all your API tokens and regenerate new ones.</Note>
  </Step>
</Steps>

## Set up your CI/CD platform

<Steps>
  <Step title="Store the Diversion client ID">
    Store it as an environment variable named `USER_POOL_CLIENT_ID` with the value `j084768v4hd6j1pf8df4h4c47`.<br />
    It will be read and used by the `dv` client in the workflow.

    Here are some relevant docs for storing environment variables in popular CI/CD platforms:

    * [<span>Jenkins <Icon icon="arrow-up-right-from-square" iconType="solid" /></span>](https://www.jenkins.io/doc/pipeline/tour/environment/)
    * [<span>CircleCI <Icon icon="arrow-up-right-from-square" iconType="solid" /></span>](https://circleci.com/docs/set-environment-variable/#set-an-environment-variable-in-a-project)
    * [<span>TravisCI <Icon icon="arrow-up-right-from-square" iconType="solid" /></span>](https://docs.travis-ci.com/user/environment-variables/)
    * [<span>TeamCity <Icon icon="arrow-up-right-from-square" iconType="solid" /></span>](https://www.jetbrains.com/help/teamcity/typed-parameters.html#How+to+Create+a+New+Parameter)
    * [<span>Bitrise <Icon icon="arrow-up-right-from-square" iconType="solid" /></span>](https://devcenter.bitrise.io/en/builds/environment-variables.html)
  </Step>

  <Step title="Store the API Token securely">
    <Note>Don't store the API Token as a plain environment variable! If your CI/CD platform provides a secure
    secret storage, use it.</Note>
    Here are some relevant docs for storing secrets in popular CI/CD platforms:

    * [<span>Jenkins <Icon icon="arrow-up-right-from-square" iconType="solid" /></span>](https://www.jenkins.io/doc/developer/security/secrets/#storing-secrets-on-disk)
    * [<span>CircleCI <Icon icon="arrow-up-right-from-square" iconType="solid" /></span>](https://circleci.com/docs/security-recommendations/)
    * [<span>TravisCI <Icon icon="arrow-up-right-from-square" iconType="solid" /></span>](https://docs.travis-ci.com/user/environment-variables/#defining-variables-in-repository-settings)
    * [<span>TeamCity <Icon icon="arrow-up-right-from-square" iconType="solid" /></span>](https://www.jetbrains.com/help/teamcity/hashicorp-vault.html)
    * [<span>Bitrise <Icon icon="arrow-up-right-from-square" iconType="solid" /></span>](https://devcenter.bitrise.io/en/builds/secrets.html)

    If your platform doesn't support secure secrets handling, you can use external secret handling tools:

    * [<span>Hashicorp Vault <Icon icon="arrow-up-right-from-square" iconType="solid" /></span>](https://www.vaultproject.io/) (has a plugin for TeamCity)
    * [<span>Akeyless <Icon icon="arrow-up-right-from-square" iconType="solid" /></span>](https://docs.akeyless.io/docs/akeyless-overview) (has a plugin for TeamCity)
    * [<span>Azure Key Vault <Icon icon="arrow-up-right-from-square" iconType="solid" /></span>](https://azure.microsoft.com/en-us/products/key-vault) (has a plugin for TeamCity)
    * [<span>Google Secret Manager <Icon icon="arrow-up-right-from-square" iconType="solid" /></span>](https://cloud.google.com/security/products/secret-manager)
    * [<span>AWS Secrets Manager <Icon icon="arrow-up-right-from-square" iconType="solid" /></span>](https://aws.amazon.com/secrets-manager/)
  </Step>
</Steps>

## Create a build step in your CI/CD workflow

### Install the Diversion client, authenticate it and clone your repo

In your CI/CD step editor or `yml` file, create a new *Shell* build step with the following content:

<CodeGroup>
  ```bash Mac/Linux theme={null}
  # Download Diversion client
  curl -sL https://get.diversion.dev/unix | bash ; export PATH="$HOME/.diversion/bin:$PATH"
  # Start the Diversion agent in the background and wait for it to start
  dv --agent --bkg
  sleep 2
  # Authenticate Diversion
  dv authenticate $API_TOKEN
  # Clone your repository and wait for sync to complete
  dv clone -new-workspace my-repository
  cd my-repository
  dv status
  ```

  ```powershell Windows theme={null}
  # Download Diversion client
  . ([Scriptblock]::Create((([System.Text.Encoding]::ASCII).getString((Invoke-WebRequest -Uri "https://get.diversion.dev/win-ci").Content))))
  # Start the Diversion agent in the background and wait for it to start
  dv --agent --bkg
  Start-Sleep -Seconds 2
  # Authenticate Diversion
  dv authenticate $API_TOKEN
  # Clone your repository and wait for sync to complete
  dv clone -new-workspace my-repository
  cd my-repository
  dv status
  ```
</CodeGroup>

<Note>Replace `$API_TOKEN` with the appropriate way to reference your secret from the secure storage.
Consult your platform's docs and the secure storage docs.</Note>
<Note>Replace `my-repository` with the name of your repository.</Note>
<Note>`dv status` will block until all the files are downloaded. This is important before starting to work.
It will also output the workspace ID if you want to reuse it for the next runs or view it in the web app.</Note>
<Note>`-new-workspace` will create a new workspace for each run of the CI/CD workflow. Passing a workspace argument here
is important, or else the clone command will prompt for user input and block. See `dv help clone` for details.</Note>

## Add the rest of your CI/CD workflow

That's it. You're all set to use your Diversion repo in your CI/CD workflow. You can also use any CLI commands you would
use with `dv` when running locally.

## A Jenkins example

Be sure to replace the placeholders with your actual values. Also note that this syntax is for a Windows node, so you may need to adjust it for your specific setup.

```groovy theme={null}
pipeline 
{
    agent 
    {
        any
    }

    environment
    {
        USER_POOL_CLIENT_ID = "j084768v4hd6j1pf8df4h4c47"
        DV_WORKSPACE = "<Workspace ID>" //Found in Diversion using 'dv workspace' command
        DV_REPO = "<Diversion Repository Name>" //Your repository name
    }

    stages
    {
        stage('Sync Repository')
        {
            steps
            {
                script
                {
                    // Checking if Diversion CLI is installed and installing from API if not
                    if (!fileExists("${USERPROFILE}\\.diversion\\bin\\dv.exe"))
                    {
                        echo "Diversion not installed at ${USERPROFILE}\\.diversion\\bin\\dv.exe, installing..."
                        powershell 'iwr https://get.diversion.dev/win-ci | iex'
                    }

                    //Authenticating Diversion CLI
                    withCredentials([string(credentialsId: '<Jenkins Credential ID>', variable: 'API_TOKEN')]) //Insert your credential ID found in Jenkins Credentials
                    {
                        echo "Diversion CLI installed, authenticating..."
                        bat "dv authenticate %API_TOKEN%"
                    }

                    //Cloning repository if it is not already cloned
                    if (!fileExists("${WORKSPACE}\\${DV_REPO}\\.diversion"))
                    {                           
                        echo "Diversion authenticated, empty folder found, cloning repository..."
                        bat "dv clone ${DV_REPO} -workspace ${DV_WORKSPACE}"
                    }

                    //Pulling latest changes if repository is already cloned
                    else
                    {
                        echo "Diversion repository already cloned, pulling latest changes..."
                        bat "cd ${WORKSPACE}\\${DV_REPO} && dv update"
                    }

                    //Displaying status of repository until tasks complete (so we do not start more tasks until it is done)
                    bat "cd ${WORKSPACE}\\${DV_REPO} && dv status"
                }
            }
        }
    }
}
```
