# GitLab CI/CD

GitLab CI/CD provides excellent Docker support with Docker-in-Docker (DinD) services, making it perfect for KushoAI test integration.

## Prerequisites

- **Docker-in-Docker**: GitLab runners with Docker and DinD service support
- **Registry Access**: Ability to pull from public ECR repositories
- **Variables Management**: GitLab CI/CD Variables for configuration

## Docker Image

All execution uses the Kusho test runner Docker image:
```
public.ecr.aws/y5g4u6y7/kusho-test-runner:latest
```

## Setup Instructions

### 1. Create `.gitlab-ci.yml`

Create a `.gitlab-ci.yml` file in your repository root:

### 2. Basic Pipeline Configuration

```yaml
stages:
  - test

variables:
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: "/certs"

kusho_tests:
  stage: test
  image: docker:24.0.0
  services:
    - docker:24.0.0-dind
  script:
    - docker run --rm \
        -e BASE_URL="${KUSHO_BASE_URL:-https://be.kusho.ai}" \
        -e ENVIRONMENT_ID="${ENVIRONMENT_ID}" \
        -e API_KEY="${KUSHO_API_KEY}" \
        -e CI_COMMIT_SHA="${CI_COMMIT_SHA}" \
        -e CI_COMMIT_MESSAGE="${CI_COMMIT_MESSAGE}" \
        -e TEST_SUITE_UUID="${TEST_SUITE_UUID}" \
        public.ecr.aws/y5g4u6y7/kusho-test-runner:latest
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
```

### 3. Configure GitLab CI/CD Variables

Navigate to your GitLab project → Settings → CI/CD → Variables

#### Protected Variables (Sensitive Data)
| Variable Name | Value | Protected | Masked |
|---------------|-------|-----------|--------|
| `KUSHO_API_KEY` | Your Kusho API key | ✓ | ✓ |

#### Regular Variables (Configuration)
| Variable Name | Value | Example |
|---------------|-------|---------|
| `ENVIRONMENT_ID` | Target environment ID | `2` |
| `TEST_SUITE_UUID` | Comma-separated UUIDs | `uuid1,uuid2` |
| `KUSHO_BASE_URL` | Base URL (optional) | `https://be.kusho.ai` |

## Execution Methods

### 1. Execute by Test Suite UUID

```yaml
test_by_uuid:
  stage: test
  image: docker:24.0.0
  services:
    - docker:24.0.0-dind
  script:
    - docker run --rm \
        -e BASE_URL="${KUSHO_BASE_URL:-https://be.kusho.ai}" \
        -e ENVIRONMENT_ID="${ENVIRONMENT_ID}" \
        -e API_KEY="${KUSHO_API_KEY}" \
        -e CI_COMMIT_SHA="${CI_COMMIT_SHA}" \
        -e CI_COMMIT_MESSAGE="${CI_COMMIT_MESSAGE}" \
        -e TEST_SUITE_UUID="${TEST_SUITE_UUID}" \
        public.ecr.aws/y5g4u6y7/kusho-test-runner:latest
```

### 2. Execute by Group ID

```yaml
test_by_group:
  stage: test
  image: docker:24.0.0
  services:
    - docker:24.0.0-dind
  script:
    - docker run --rm \
        -e BASE_URL="${KUSHO_BASE_URL:-https://be.kusho.ai}" \
        -e ENVIRONMENT_ID="${ENVIRONMENT_ID}" \
        -e API_KEY="${KUSHO_API_KEY}" \
        -e CI_COMMIT_SHA="${CI_COMMIT_SHA}" \
        -e CI_COMMIT_MESSAGE="${CI_COMMIT_MESSAGE}" \
        -e GROUP_ID="${GROUP_ID}" \
        public.ecr.aws/y5g4u6y7/kusho-test-runner:latest
```

### 3. Execute by Tags

```yaml
test_by_tags:
  stage: test
  image: docker:24.0.0
  services:
    - docker:24.0.0-dind
  script:
    - docker run --rm \
        -e BASE_URL="${KUSHO_BASE_URL:-https://be.kusho.ai}" \
        -e ENVIRONMENT_ID="${ENVIRONMENT_ID}" \
        -e API_KEY="${KUSHO_API_KEY}" \
        -e CI_COMMIT_SHA="${CI_COMMIT_SHA}" \
        -e CI_COMMIT_MESSAGE="${CI_COMMIT_MESSAGE}" \
        -e TAGS="${TEST_TAGS}" \
        public.ecr.aws/y5g4u6y7/kusho-test-runner:latest
```

### 4. Execute E2E Workflows by UUID

```yaml
test_e2e:
  stage: test
  image: docker:24.0.0
  services:
    - docker:24.0.0-dind
  script:
    - docker run --rm \
        -e BASE_URL="${KUSHO_BASE_URL:-https://be.kusho.ai}" \
        -e ENVIRONMENT_ID="${ENVIRONMENT_ID}" \
        -e API_KEY="${KUSHO_API_KEY}" \
        -e CI_COMMIT_SHA="${CI_COMMIT_SHA}" \
        -e CI_COMMIT_MESSAGE="${CI_COMMIT_MESSAGE}" \
        -e E2E_TEST_SUITE_UUID="${E2E_TEST_SUITE_UUID}" \
        -e EXECUTION_PROFILE_UUID="${EXECUTION_PROFILE_UUID}" \
        public.ecr.aws/y5g4u6y7/kusho-test-runner:latest
```

### 5. Execute E2E Workflows by Tags

```yaml
test_e2e_by_tags:
  stage: test
  image: docker:24.0.0
  services:
    - docker:24.0.0-dind
  script:
    - docker run --rm \
        -e BASE_URL="${KUSHO_BASE_URL:-https://be.kusho.ai}" \
        -e ENVIRONMENT_ID="${ENVIRONMENT_ID}" \
        -e API_KEY="${KUSHO_API_KEY}" \
        -e CI_COMMIT_SHA="${CI_COMMIT_SHA}" \
        -e CI_COMMIT_MESSAGE="${CI_COMMIT_MESSAGE}" \
        -e E2E_TEST_SUITE_TAGS="${E2E_TEST_SUITE_TAGS}" \
        -e E2E_PROFILE_TAGS="${E2E_PROFILE_TAGS}" \
        public.ecr.aws/y5g4u6y7/kusho-test-runner:latest
```

## Complete Pipeline Examples

### Multi-Stage Testing Pipeline

```yaml
stages:
  - smoke
  - integration
  - e2e

variables:
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: "/certs"

.kusho_test_template: &kusho_test
  image: docker:24.0.0
  services:
    - docker:24.0.0-dind
  before_script:
    - docker info

smoke_tests:
  <<: *kusho_test
  stage: smoke
  script:
    - docker run --rm \
        -e BASE_URL="${KUSHO_BASE_URL:-https://be.kusho.ai}" \
        -e ENVIRONMENT_ID="${ENVIRONMENT_ID}" \
        -e API_KEY="${KUSHO_API_KEY}" \
        -e CI_COMMIT_SHA="${CI_COMMIT_SHA}" \
        -e CI_COMMIT_MESSAGE="${CI_COMMIT_MESSAGE}" \
        -e TAGS="smoke" \
        public.ecr.aws/y5g4u6y7/kusho-test-runner:latest
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

integration_tests:
  <<: *kusho_test
  stage: integration
  script:
    - docker run --rm \
        -e BASE_URL="${KUSHO_BASE_URL:-https://be.kusho.ai}" \
        -e ENVIRONMENT_ID="${ENVIRONMENT_ID}" \
        -e API_KEY="${KUSHO_API_KEY}" \
        -e CI_COMMIT_SHA="${CI_COMMIT_SHA}" \
        -e CI_COMMIT_MESSAGE="${CI_COMMIT_MESSAGE}" \
        -e TAGS="integration" \
        public.ecr.aws/y5g4u6y7/kusho-test-runner:latest
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
    - if: $CI_COMMIT_BRANCH == "develop"

e2e_tests:
  <<: *kusho_test
  stage: e2e
  script:
    - docker run --rm \
        -e BASE_URL="${KUSHO_BASE_URL:-https://be.kusho.ai}" \
        -e ENVIRONMENT_ID="${ENVIRONMENT_ID}" \
        -e API_KEY="${KUSHO_API_KEY}" \
        -e CI_COMMIT_SHA="${CI_COMMIT_SHA}" \
        -e CI_COMMIT_MESSAGE="${CI_COMMIT_MESSAGE}" \
        -e E2E_TEST_SUITE_UUID="${E2E_TEST_SUITE_UUID}" \
        -e EXECUTION_PROFILE_UUID="${EXECUTION_PROFILE_UUID}" \
        public.ecr.aws/y5g4u6y7/kusho-test-runner:latest
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  when: manual
  allow_failure: true

e2e_smoke_tests:
  <<: *kusho_test
  stage: e2e
  script:
    - docker run --rm \
        -e BASE_URL="${KUSHO_BASE_URL:-https://be.kusho.ai}" \
        -e ENVIRONMENT_ID="${ENVIRONMENT_ID}" \
        -e API_KEY="${KUSHO_API_KEY}" \
        -e CI_COMMIT_SHA="${CI_COMMIT_SHA}" \
        -e CI_COMMIT_MESSAGE="${CI_COMMIT_MESSAGE}" \
        -e E2E_TEST_SUITE_TAGS="smoke,critical" \
        -e E2E_PROFILE_TAGS="fast" \
        public.ecr.aws/y5g4u6y7/kusho-test-runner:latest
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
    - if: $CI_COMMIT_BRANCH == "develop"
```

### Multi-Environment Pipeline

```yaml
stages:
  - test-staging
  - test-production

variables:
  DOCKER_DRIVER: overlay2

.test_template: &test_template
  image: docker:24.0.0
  services:
    - docker:24.0.0-dind

test_staging:
  <<: *test_template
  stage: test-staging
  script:
    - docker run --rm \
        -e BASE_URL="${KUSHO_BASE_URL:-https://be.kusho.ai}" \
        -e ENVIRONMENT_ID="2" \
        -e API_KEY="${KUSHO_API_KEY}" \
        -e CI_COMMIT_SHA="${CI_COMMIT_SHA}" \
        -e CI_COMMIT_MESSAGE="${CI_COMMIT_MESSAGE}" \
        -e TAGS="smoke,regression" \
        public.ecr.aws/y5g4u6y7/kusho-test-runner:latest
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"

test_production:
  <<: *test_template
  stage: test-production
  script:
    - docker run --rm \
        -e BASE_URL="${KUSHO_BASE_URL:-https://be.kusho.ai}" \
        -e ENVIRONMENT_ID="1" \
        -e API_KEY="${KUSHO_API_KEY}" \
        -e CI_COMMIT_SHA="${CI_COMMIT_SHA}" \
        -e CI_COMMIT_MESSAGE="${CI_COMMIT_MESSAGE}" \
        -e TAGS="smoke" \
        public.ecr.aws/y5g4u6y7/kusho-test-runner:latest
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  when: manual
```

## GitLab CI/CD Features

### Built-in Environment Variables

GitLab automatically provides commit information:
- `$CI_COMMIT_SHA` - Full commit SHA
- `$CI_COMMIT_MESSAGE` - Commit message
- `$CI_COMMIT_BRANCH` - Current branch name
- `$CI_PIPELINE_SOURCE` - Pipeline trigger source

### Rules for Conditional Execution

```yaml
rules:
  - if: $CI_PIPELINE_SOURCE == "push"
  - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  - if: $CI_COMMIT_BRANCH == "main"
  - if: $CI_COMMIT_BRANCH =~ /^feature\/.*/
```

### Parallel Jobs

```yaml
test_api_suite_1:
  extends: .kusho_test_template
  variables:
    TEST_SUITE_UUID: "uuid1,uuid2"

test_api_suite_2:
  extends: .kusho_test_template
  variables:
    TEST_SUITE_UUID: "uuid3,uuid4"
```

### Artifacts and Reports

```yaml
kusho_tests:
  stage: test
  script:
    - docker run --rm \
        -v $(pwd)/results:/results \
        -e BASE_URL="${KUSHO_BASE_URL:-https://be.kusho.ai}" \
        -e ENVIRONMENT_ID="${ENVIRONMENT_ID}" \
        -e API_KEY="${KUSHO_API_KEY}" \
        -e TEST_SUITE_UUID="${TEST_SUITE_UUID}" \
        public.ecr.aws/y5g4u6y7/kusho-test-runner:latest
  artifacts:
    when: always
    expire_in: 1 week
    reports:
      junit: results/junit.xml
    paths:
      - results/
```

## GitLab-Specific Configurations

### Using GitLab Container Registry

If you want to cache the Docker image in your GitLab container registry:

```yaml
pull_and_cache:
  stage: .pre
  image: docker:24.0.0
  services:
    - docker:24.0.0-dind
  script:
    - docker pull public.ecr.aws/y5g4u6y7/kusho-test-runner:latest
    - docker tag public.ecr.aws/y5g4u6y7/kusho-test-runner:latest $CI_REGISTRY_IMAGE/kusho-test-runner:latest
    - docker push $CI_REGISTRY_IMAGE/kusho-test-runner:latest
  rules:
    - if: $CI_PIPELINE_SOURCE == "schedule"
```

### Environment-Specific Variables

Use GitLab environments for different deployment stages:

```yaml
test_staging:
  stage: test
  environment:
    name: staging
  variables:
    ENVIRONMENT_ID: "2"
  script:
    - docker run --rm \
        -e ENVIRONMENT_ID="${ENVIRONMENT_ID}" \
        # ... other variables
```

### Integration with GitLab Issues

```yaml
create_issue_on_failure:
  stage: .post
  image: alpine:latest
  script:
    - apk add --no-cache curl
    - |
      curl --request POST \
        --header "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \
        --header "Content-Type: application/json" \
        --data '{"title":"Test Failure in Pipeline","description":"Tests failed in pipeline '${CI_PIPELINE_ID}'"}' \
        "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/issues"
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"
      when: on_failure
```

## Best Practices

### Security
- Use protected and masked variables for sensitive data
- Implement proper branch protection rules
- Use GitLab CI/CD security scanning features

### Performance
- Use YAML anchors to reduce duplication
- Implement caching strategies for Docker layers
- Use parallel jobs for independent test suites

### Organization
- Use includes to modularize your pipeline configuration
- Implement consistent naming conventions
- Use extends for job templates

### Monitoring
- Set up GitLab notifications for pipeline failures
- Use GitLab's pipeline analytics
- Implement custom metrics collection

## Troubleshooting

### Common Issues

1. **Docker-in-Docker Issues**
   ```yaml
   variables:
     DOCKER_TLS_CERTDIR: "/certs"
     DOCKER_DRIVER: overlay2
   ```

2. **Registry Access Problems**
   - Ensure runner has internet access
   - Check DNS resolution for ECR registry

3. **Variable Issues**
   - Verify variable names and values in project settings
   - Check variable scope (project vs group vs instance)

### Debug Mode

Enable debug logging:
```yaml
variables:
  CI_DEBUG_TRACE: "true"
```

### Service Health Checks

```yaml
before_script:
  - docker info
  - docker version
  - echo "Docker service is ready"
```

## Integration Examples

### Slack Notifications

```yaml
notify_slack:
  stage: .post
  image: alpine:latest
  script:
    - apk add --no-cache curl
    - |
      curl -X POST -H 'Content-type: application/json' \
        --data '{"text":"Pipeline '${CI_PIPELINE_ID}' completed with status: '${CI_JOB_STATUS}'"}' \
        ${SLACK_WEBHOOK_URL}
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"
      when: always
```

### Jira Integration

```yaml
update_jira:
  stage: .post
  image: alpine:latest
  script:
    - apk add --no-cache curl
    - |
      curl -u ${JIRA_USER}:${JIRA_TOKEN} \
        -X POST \
        -H "Content-Type: application/json" \
        -d '{"body":"Pipeline completed for commit '${CI_COMMIT_SHA}'"}' \
        "${JIRA_URL}/rest/api/2/issue/${JIRA_ISSUE}/comment"
  rules:
    - if: $CI_COMMIT_MESSAGE =~ /JIRA-\d+/
```
