# Jenkins

Load KeyEnv secrets in Jenkins pipelines.

Source: https://keyenv.dev/docs/guides/jenkins/

Load KeyEnv secrets in your Jenkins CI/CD pipelines.

## Prerequisites

- Jenkins with Pipeline plugin
- KeyEnv service token with read access

## Setup

### 1. Store Your Token

Add your KeyEnv token to Jenkins credentials:

1. Go to **Manage Jenkins** > **Credentials**
2. Select the appropriate scope (global or folder)
3. Click **Add Credentials**
4. Choose **Secret text**
5. Set ID to `keyenv-token`
6. Paste your KeyEnv service token

### 2. Create Pipeline

#### Declarative Pipeline

```groovy
pipeline {
    agent any

    environment {
        KEYENV_TOKEN = credentials('keyenv-token')
    }

    stages {
        stage('Setup') {
            steps {
                sh '''
                    curl -fsSL https://keyenv.dev/install.sh | bash
                    export PATH="$HOME/.keyenv/bin:$PATH"
                '''
            }
        }

        stage('Build') {
            steps {
                sh '''
                    export PATH="$HOME/.keyenv/bin:$PATH"
                    keyenv run -p YOUR_PROJECT_ID -e production -- npm ci
                    keyenv run -p YOUR_PROJECT_ID -e production -- npm run build
                '''
            }
        }

        stage('Test') {
            steps {
                sh '''
                    export PATH="$HOME/.keyenv/bin:$PATH"
                    keyenv run -p YOUR_PROJECT_ID -e production -- npm test
                '''
            }
        }

        stage('Deploy') {
            when {
                branch 'main'
            }
            steps {
                sh '''
                    export PATH="$HOME/.keyenv/bin:$PATH"
                    keyenv run -p YOUR_PROJECT_ID -e production -- npm run deploy
                '''
            }
        }
    }
}
```

#### Scripted Pipeline

```groovy
node {
    withCredentials([string(credentialsId: 'keyenv-token', variable: 'KEYENV_TOKEN')]) {
        stage('Setup') {
            sh 'curl -fsSL https://keyenv.dev/install.sh | bash'
        }

        stage('Build') {
            sh '''
                export PATH="$HOME/.keyenv/bin:$PATH"
                keyenv run -p YOUR_PROJECT_ID -e production -- npm ci
                keyenv run -p YOUR_PROJECT_ID -e production -- npm run build
            '''
        }

        stage('Test') {
            sh '''
                export PATH="$HOME/.keyenv/bin:$PATH"
                keyenv run -p YOUR_PROJECT_ID -e production -- npm test
            '''
        }
    }
}
```

## Environment-Based Deployment

Map Jenkins branches to KeyEnv environments:

```groovy
pipeline {
    agent any

    environment {
        KEYENV_TOKEN = credentials('keyenv-token')
        KEYENV_ENV = "${env.BRANCH_NAME == 'main' ? 'production' : 'staging'}"
    }

    stages {
        stage('Deploy') {
            steps {
                sh '''
                    export PATH="$HOME/.keyenv/bin:$PATH"
                    keyenv run -p YOUR_PROJECT_ID -e $KEYENV_ENV -- npm run deploy
                '''
            }
        }
    }
}
```

## Pull Secrets to .env File

If you need a `.env` file instead of injecting directly:

```groovy
stage('Setup Secrets') {
    steps {
        sh '''
            export PATH="$HOME/.keyenv/bin:$PATH"
            keyenv pull -p YOUR_PROJECT_ID -e production -o .env
        '''
    }
}
```

## Multi-Branch Pipeline

```groovy
pipeline {
    agent any

    environment {
        KEYENV_TOKEN = credentials('keyenv-token')
    }

    stages {
        stage('Determine Environment') {
            steps {
                script {
                    env.KEYENV_ENV = sh(
                        script: '''
                            case "$BRANCH_NAME" in
                                main) echo "production" ;;
                                staging) echo "staging" ;;
                                *) echo "development" ;;
                            esac
                        ''',
                        returnStdout: true
                    ).trim()
                }
            }
        }

        stage('Build & Test') {
            steps {
                sh '''
                    export PATH="$HOME/.keyenv/bin:$PATH"
                    keyenv run -p YOUR_PROJECT_ID -e $KEYENV_ENV -- npm ci
                    keyenv run -p YOUR_PROJECT_ID -e $KEYENV_ENV -- npm test
                '''
            }
        }
    }
}
```

## Docker Builds

Pass secrets to Docker builds:

```groovy
stage('Docker Build') {
    steps {
        sh '''
            export PATH="$HOME/.keyenv/bin:$PATH"

            # Export secrets as build args
            eval $(keyenv export -p YOUR_PROJECT_ID -e production --format shell)

            docker build \
                --build-arg DATABASE_URL=$DATABASE_URL \
                --build-arg API_KEY=$API_KEY \
                -t myapp:latest .
        '''
    }
}
```

## Shared Library

Create a reusable function in a Jenkins shared library:

```groovy
// vars/withKeyEnv.groovy
def call(String projectId, String environment, Closure body) {
    withCredentials([string(credentialsId: 'keyenv-token', variable: 'KEYENV_TOKEN')]) {
        sh 'curl -fsSL https://keyenv.dev/install.sh | bash 2>/dev/null || true'
        sh """
            export PATH="\$HOME/.keyenv/bin:\$PATH"
            keyenv run -p ${projectId} -e ${environment} -- ${body()}
        """
    }
}
```

Usage:

```groovy
pipeline {
    stages {
        stage('Test') {
            steps {
                withKeyEnv('my-project', 'staging') {
                    'npm test'
                }
            }
        }
    }
}
```

## Security Best Practices

1. **Use credentials binding** - Never hardcode tokens in Jenkinsfiles
2. **Limit token scope** - Create project-specific tokens
3. **Mask secrets in logs** - Jenkins masks `credentials()` values automatically
4. **Use folder-scoped credentials** - Limit access to specific projects

## Troubleshooting

### CLI Not Found

Ensure the PATH is set in every stage:

```groovy
sh '''
    export PATH="$HOME/.keyenv/bin:$PATH"
    keyenv --version
'''
```

### Token Not Working

Verify the credential is accessible:

```groovy
withCredentials([string(credentialsId: 'keyenv-token', variable: 'KEYENV_TOKEN')]) {
    sh 'echo "Token length: ${#KEYENV_TOKEN}"'
}
```

### Permission Denied

Check your service token has access to the project and environment:

```groovy
sh '''
    export PATH="$HOME/.keyenv/bin:$PATH"
    keyenv whoami  # Shows token info
'''
```
