Skip to content
Back to skills

1643 Gitlab Ci Local Guide 04d6a916

CSecurity

Complete guide for setting up and using gitlab-ci-local to test GitLab CI/CD pipelines locally.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
devopspythongoshellbashnodedockertestingdebugginggitapi

Works with

  • cli
  • api

Security analysis

C71/100
  • criticalExfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study
  • criticalSends environment variables or credentials to an external URL
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 1643-gitlab-ci-local-guide_04d6a916 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 1643 Gitlab Ci Local Guide 04d6a916?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 1643 Gitlab Ci Local Guide 04d6a916
[![Security: C — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-1643-gitlab-ci-local-guide-04d6a916/badge)](https://www.skillsdirectory.com/skills/tools-only-1643-gitlab-ci-local-guide-04d6a916)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# GitLab CI Local Testing Guide

Complete guide for setting up and using gitlab-ci-local to test GitLab CI/CD pipelines locally.

## Overview

[gitlab-ci-local](https://github.com/firecow/gitlab-ci-local) is a CLI tool that runs GitLab CI/CD pipelines locally, eliminating commit-push-debug cycles.

**Why use it:**

- Test CI/CD pipeline changes before pushing to GitLab
- Debug pipeline failures locally with full access to logs and artifacts
- Validate release workflows without creating actual releases
- Save CI runner minutes and reduce feedback time

## Prerequisites

Before setup, ensure you have:

1. **Node.js** (version 14 or higher)

   ```bash
   node --version  # Should be >= 14.x
   ```

2. **Container Engine** (Docker or Podman)

   ```bash
   # Check if Docker is available
   docker --version

   # OR check if Podman is available
   podman --version
   ```

3. **gitlab-ci-local** installed globally

   ```bash
   npm install -g gitlab-ci-local

   # Verify installation
   gitlab-ci-local --version
   ```

## Quick Start

### 1. Get a GitLab API Token

Create a personal access token from your GitLab instance:

1. Log in to your GitLab instance (e.g., <https://sourcery.assaabloy.net>)
2. Go to **User Settings** → **Access Tokens**
3. Create a new token with these scopes:

   - `api` - Full API access
   - `read_repository` - Read repository data
   - `write_repository` - Write repository data (for releases)
   - `read_registry` - Read package registry
   - `write_registry` - Publish packages

4. **IMPORTANT**: Copy the token immediately - you cannot view it again!

### 2. Configure Home Directory Variables

Create a global configuration that works for all projects:

```bash
# Create the directory if it doesn't exist
mkdir -p $HOME/.gitlab-ci-local

# Create the variables file
cat > $HOME/.gitlab-ci-local/variables.yml <<'EOF'
---
# GitLab CI Local - Home Variables Configuration
# This file contains global CI/CD variables available across all projects

global:
  # Authentication tokens - replace with your actual token
  GITLAB_TOKEN: glpat-YOUR_TOKEN_HERE
  CI_JOB_TOKEN: glpat-YOUR_TOKEN_HERE
EOF
```

**Security Note**: This file is stored in your home directory and is NOT tracked in git.

### 3. Test Your Setup

From the project root directory:

```bash
# List all jobs in the pipeline
gitlab-ci-local --list

# Run a specific job
gitlab-ci-local test:python

# Run the entire pipeline
gitlab-ci-local
```

## Configuration Files

gitlab-ci-local uses multiple configuration files with different purposes:

### Project-Level Configuration (Tracked in Git)

#### `.gitlab-ci-local-variables.yml`

Contains project-specific CI/CD variables that are safe to commit:

```yaml
# GitLab CI variables for local testing
CI_SERVER_URL: https://gitlab.example.com
CI_SERVER_HOST: gitlab.example.com
CI_PROJECT_PATH: group/project
CI_PROJECT_ID: 1234
CI_API_V4_URL: https://gitlab.example.com/api/v4
CI_PROJECT_URL: https://gitlab.example.com/group/project
CI_PROJECT_NAME: project
CI_PROJECT_NAMESPACE: group
CI_COMMIT_BRANCH: main
CI_DEFAULT_BRANCH: main
# Use the real GitLab token for authentication in local testing
CI_JOB_TOKEN: $GITLAB_TOKEN
```

**Location**: Project root (committed to git) **Purpose**: Project-specific variables that don't contain secrets

### Local Secrets (NOT Tracked in Git)

#### `.gitlab-ci-local-env`

Contains secrets and CLI configuration options:

```bash
# Secrets for local testing (CLI options format)
GITLAB_TOKEN=glpat-YOUR_TOKEN_HERE
CI_JOB_TOKEN=glpat-YOUR_TOKEN_HERE

# Optional: Other secrets
WOKWI_CLI_TOKEN=wok_YOUR_WOKWI_TOKEN
```

**Location**: Project root (added to .gitignore) **Purpose**: Project-specific secrets and CLI options **Format**: Shell environment variable format (`KEY=value`)

### User-Global Configuration (Home Directory)

#### `$HOME/.gitlab-ci-local/variables.yml`

**This is the recommended approach** for storing tokens that work across all projects:

```yaml
---
# GitLab CI Local - Home Variables Configuration
# This file contains global CI/CD variables available across all projects

global:
  # Authentication tokens
  GITLAB_TOKEN: glpat-YOUR_TOKEN_HERE
  CI_JOB_TOKEN: glpat-YOUR_TOKEN_HERE
```

**Location**: `~/.gitlab-ci-local/variables.yml` **Purpose**: User-wide variables that apply to all projects **Format**: YAML with `global:` section **Security**: Stored in your home directory, never committed to any repository

## CLI Usage

### Common Commands

```bash
# List all jobs (excludes jobs with when:never)
gitlab-ci-local --list

# List all jobs including when:never
gitlab-ci-local --list-all

# List jobs in CSV format
gitlab-ci-local --list-csv

# Preview expanded GitLab CI YAML (with all includes/extends resolved)
gitlab-ci-local --preview

# Run a specific job
gitlab-ci-local <job-name>

# Run multiple specific jobs
gitlab-ci-local job1 job2 job3

# Run all jobs in a specific stage
gitlab-ci-local --stage test

# Run a job and all its dependencies (needs)
gitlab-ci-local --needs release

# Pass additional variables
gitlab-ci-local --variable MY_VAR=value --variable ANOTHER=123 job-name

# Use a different variables file
gitlab-ci-local --variables-file custom-variables.yml

# Enable timestamp logging
gitlab-ci-local --timestamps job-name

# Fetch latest external includes before running
gitlab-ci-local --fetch-includes
```

### Running Specific Scenarios

#### Test Before Pushing

```bash
# Run all test jobs
gitlab-ci-local --stage test

# Run linting only
gitlab-ci-local lint:ruff

# Run tests for specific Python version
gitlab-ci-local test:python
```

#### Test Release Workflow

```bash
# Run release job with all dependencies
gitlab-ci-local --needs release

# Check what the release job would do (dry-run via preview)
gitlab-ci-local --preview | grep -A 50 "^release:"
```

#### Debug Failed Jobs

```bash
# Run with timestamps to see timing issues
gitlab-ci-local --timestamps failing-job

# Check the expanded configuration
gitlab-ci-local --preview

# Verify variables are set correctly
gitlab-ci-local --list-json | jq '.[] | select(.name=="failing-job")'
```

## Troubleshooting

### Common Issues and Solutions

#### 1. Authentication Failures (403/401 Errors)

**Symptom**: Git push or API calls fail with authentication errors

**Possible Causes**:

- Token doesn't have required scopes
- Token expired or revoked
- Wrong token format (missing `glpat-` prefix)

**Solution**:

```bash
# Test token validity
curl -H "PRIVATE-TOKEN: $GITLAB_TOKEN" \
  "https://gitlab.example.com/api/v4/user"

# Test token scopes for package publishing
curl -H "PRIVATE-TOKEN: $GITLAB_TOKEN" \
  "https://gitlab.example.com/api/v4/projects/1234/packages/pypi"

# Test git authentication with token
git ls-remote $(git remote get-url origin | sed "s|://|://oauth2:$GITLAB_TOKEN@|") | head -5
```

#### 2. Token Variables Not Available

**Symptom**: Jobs fail because `$GITLAB_TOKEN` is empty or undefined

**Problem**: Token not set in the correct configuration file

**Solution**: Check configuration file hierarchy:

1. First, check home directory configuration:

   ```bash
   cat $HOME/.gitlab-ci-local/variables.yml
   # Should show: GITLAB_TOKEN under global: section
   ```

2. Verify with a test job:

   ```bash
   # Create test job
   cat > .gitlab-ci-test.yml <<'EOF'
   test-token:
     stage: test
     image: alpine
     script:
       - 'echo "GITLAB_TOKEN starts with: ${GITLAB_TOKEN:0:15}..."'
       - 'echo "CI_JOB_TOKEN starts with: ${CI_JOB_TOKEN:0:15}..."'
   EOF

   # Run test
   gitlab-ci-local --file .gitlab-ci-test.yml test-token

   # Clean up
   rm .gitlab-ci-test.yml
   ```

3. If still failing, pass token via command line:

   ```bash
   gitlab-ci-local --variable GITLAB_TOKEN=$GITLAB_TOKEN job-name
   ```

#### 3. Jobs Running with Wrong Configuration

**Symptom**: Jobs use unexpected variables or configuration

**Problem**: Multiple configuration files conflicting

**Solution**: Check configuration precedence:

```bash
# gitlab-ci-local loads variables in this order (later overrides earlier):
# 1. $HOME/.gitlab-ci-local/variables.yml
# 2. .gitlab-ci-local-variables.yml (project default)
# 3. --variables-file argument
# 4. --variable CLI arguments (highest priority)

# Debug by previewing expanded config
gitlab-ci-local --preview | less
```

#### 4. glab Release Creation Fails

**Symptom**: `none of the git remotes configured for this repository point to a known GitLab host`

**Problem**: Missing `GITLAB_HOST` environment variable for self-hosted GitLab

**Solution**: Add to `.gitlab-ci.yml` release job:

```yaml
.release_base:
  variables:
    GITLAB_HOST: $CI_SERVER_HOST # Tells glab about self-hosted instance
```

## Real-World Examples

### Example 1: Testing Pipeline Changes Locally

```bash
# Make changes to .gitlab-ci.yml
vim .gitlab-ci.yml

# Preview expanded configuration
gitlab-ci-local --preview | less

# List all jobs to see what will run
gitlab-ci-local --list

# Run specific stage to test changes
gitlab-ci-local --stage test

# If successful, commit and push
git add .gitlab-ci.yml
git commit -m "ci: update pipeline configuration"
git push
```

### Example 2: Debugging a Failed Release

```bash
# Check release job configuration
gitlab-ci-local --preview | grep -A 100 "^release:"

# Verify all required variables are set
gitlab-ci-local --list-json | jq '.[] | select(.name=="release")'

# Run release job with verbose output and timestamps
gitlab-ci-local --timestamps --needs release

# If it fails, check artifacts directory
ls -la .gitlab-ci-local/artifacts/release/

# Check job logs
cat .gitlab-ci-local/output/release.log
```

### Example 3: Running Tests in Parallel

```bash
# Run all test jobs for both Python versions in parallel
# (gitlab-ci-local automatically runs matrix jobs in parallel)
gitlab-ci-local test:python

# Check artifacts for both Python versions
ls -la .gitlab-ci-local/artifacts/test-reports/
ls -la .gitlab-ci-local/artifacts/coverage/

# View coverage reports
firefox .gitlab-ci-local/artifacts/coverage/htmlcov-py3.11/index.html
```

## Variable Configuration Best Practices

### ✅ Recommended Setup

1. **For tokens and secrets**: Use `$HOME/.gitlab-ci-local/variables.yml`

   - Pros: Works across all projects, never accidentally committed
   - Cons: Must be set up once per developer workstation

2. **For project metadata**: Use `.gitlab-ci-local-variables.yml` (committed)

   - Pros: Shared with team, consistent across developers
   - Cons: Cannot contain secrets

3. **For temporary overrides**: Use `--variable` CLI flag
   - Pros: Quick testing without file changes
   - Cons: Must remember to add each time

### ❌ Common Mistakes

- ❌ Committing `.gitlab-ci-local-env` with tokens
- ❌ Forgetting to set `GITLAB_HOST` for glab in self-hosted instances
- ❌ Using `.env` format in `$HOME/.gitlab-ci-local/.env` (should be `variables.yml` in YAML)
- ❌ Testing with wrong token that lacks required scopes

## Security Considerations

### Token Storage

**✅ Safe locations**:

- `$HOME/.gitlab-ci-local/variables.yml` (user home directory)
- System keychain/credential manager
- Environment variables in your shell config (with caution)

**❌ Never store tokens in**:

- `.gitlab-ci-local-env` (unless in .gitignore)
- `.gitlab-ci-local-variables.yml` (this is tracked in git!)
- `.gitlab-ci.yml` (public in repository)
- Any file tracked by git

### Token Scope Minimization

Only grant the scopes you actually need:

| Scope              | Required For              | Risk Level                |
| ------------------ | ------------------------- | ------------------------- |
| `api`              | Full API access, releases | High - grants wide access |
| `read_repository`  | Cloning, reading code     | Low                       |
| `write_repository` | Pushing tags, releases    | Medium                    |
| `read_registry`    | Pulling packages          | Low                       |
| `write_registry`   | Publishing packages       | Medium                    |

### Token Rotation

- Rotate tokens every 90 days
- Immediately revoke tokens if compromised
- Use separate tokens for CI/CD vs local development
- Never share tokens between team members

## Advanced Usage

### Custom Container Engine

If using Podman instead of Docker:

```bash
# Set container executable
export GCL_CONTAINER_EXECUTABLE=podman

# Or use CLI flag
gitlab-ci-local --container-executable podman job-name
```

### Limit Concurrent Jobs

```bash
# Run maximum 2 jobs in parallel (useful for resource-constrained machines)
gitlab-ci-local --concurrency 2
```

### Artifact Management

```bash
# Prevent artifacts from being copied to source directory
gitlab-ci-local --no-artifacts-to-source

# Clean up Docker resources after pipeline
gitlab-ci-local --cleanup

# View artifacts location
ls -la .gitlab-ci-local/artifacts/
```

### Shell Isolation

```bash
# Enable artifact isolation for shell executor jobs
gitlab-ci-local --shell-isolation

# Force all jobs to use shell executor (for debugging)
gitlab-ci-local --force-shell-executor
```

## Additional Resources

- **gitlab-ci-local GitHub**: <https://github.com/firecow/gitlab-ci-local>
- **GitLab CI/CD Documentation**: <https://docs.gitlab.com/ee/ci/>

## Getting Help

If you encounter issues:

1. Check this troubleshooting guide
2. Run `gitlab-ci-local --preview` to see expanded configuration
3. Check `.gitlab-ci-local/output/` for job logs
4. Verify token validity with curl commands shown above
5. Ask in team chat or create an issue in the repository

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.