CI/CD Generator

v1.0.0

Generate GitHub Actions CI/CD pipelines tailored to the current project. Use when the user says 'set up CI', 'create pipeline', 'github actions', 'CI/CD', 'd...

0· 82·0 current·0 all-time
bySamih Mansour@llcsamih

Install

OpenClaw Prompt Flow

Install with OpenClaw

Best for remote or guided setup. Copy the exact prompt, then paste it into OpenClaw for llcsamih/cicd-generator.

Previewing Install & Setup.
Prompt PreviewInstall & Setup
Install the skill "CI/CD Generator" (llcsamih/cicd-generator) from ClawHub.
Skill page: https://clawhub.ai/llcsamih/cicd-generator
Keep the work scoped to this skill only.
After install, inspect the skill metadata and help me finish setup.
Use only the metadata you can verify from ClawHub; do not invent missing requirements.
Ask before making any broader environment changes.

Command Line

CLI Commands

Use the direct CLI path if you want to install manually and keep every step visible.

OpenClaw CLI

Bare skill slug

openclaw skills install cicd-generator

ClawHub CLI

Package manager switcher

npx clawhub@latest install cicd-generator
Security Scan
Capability signals
Requires OAuth token
These labels describe what authority the skill may exercise. They are separate from suspicious or malicious moderation verdicts.
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Benign
high confidence
Purpose & Capability
The name/description (CI/CD Generator for GitHub Actions) matches the SKILL.md: it inspects project files and generates workflow files. Required capabilities (reading repo files, creating .github/workflows entries) are consistent with the stated purpose.
Instruction Scope
Instructions explicitly tell the agent to read project-root files (package.json, pyproject.toml, Dockerfile, etc.) and create workflow files. This is expected for generating CI. Note: the SKILL.md does not describe how generated files are committed/pushed or how deployment credentials are obtained — it prompts the user for deploy target but does not request or manage secrets itself.
Install Mechanism
No install spec and no code files (instruction-only). This minimizes disk-write/install risk — the skill only provides runtime instructions.
Credentials
The skill requests no environment variables or credentials, which is proportionate for generating workflow content. However, some deploy targets mentioned (ECR, Docker Hub, VPS via SSH, Railway, Vercel) normally require credentials/secrets to actually deploy; the skill leaves secret management to the user/platform. That is reasonable but users should be aware the generated workflows may require adding secrets to GitHub.
Persistence & Privilege
always is false and the skill does not request persistent privileges or modify other skills/config. It only instructs generation of workflow files in the repo scope.
Assessment
This skill is coherent for generating GitHub Actions workflows, but review the outputs before committing: it will read your repository to detect stack and create .github/workflows files that run CI in your repo. If you choose deploy targets (ECR, Docker Hub, VPS, Vercel, Railway), you will need to add appropriate secrets to GitHub Actions (e.g., DOCKER_USERNAME/DOCKER_PASSWORD, AWS credentials, SSH keys) — the skill doesn't request or store those. Check the generated workflows for: pinned action versions, unwanted environment variables or secret exposures, and any commands that run untrusted code. If you want the skill to also push commits or add secrets, verify how the agent/platform will perform those actions and grant only the minimal permissions required.

Like a lobster shell, security has layers — review code before you run it.

latestvk974kkww797dvx8abb9v8bj1nh84f4z2
82downloads
0stars
1versions
Updated 2w ago
v1.0.0
MIT-0

CI/CD Generator

Generate production-grade GitHub Actions workflows by analyzing the current project structure. Supports any stack, any deploy target.

Step 1: Detect Project Stack

Read the project root and identify what exists. Run these checks in parallel:

Glob: package.json, pnpm-workspace.yaml, turbo.json, lerna.json
Glob: requirements.txt, pyproject.toml, setup.py, Pipfile, poetry.lock
Glob: Dockerfile, docker-compose.yml, docker-compose.yaml
Glob: go.mod, Cargo.toml, Gemfile, build.gradle, pom.xml
Glob: vercel.json, next.config.*, nuxt.config.*, svelte.config.*
Glob: .github/workflows/*.yml, .github/workflows/*.yaml

Build a detection summary:

SignalStack
package.json + next.config.*Next.js
package.json + nuxt.config.*Nuxt
package.json + svelte.config.*SvelteKit
package.json (no framework config)Generic Node.js
requirements.txt or pyproject.tomlPython
go.modGo
Cargo.tomlRust
DockerfileDocker build
pnpm-workspace.yaml or turbo.jsonMonorepo
vercel.jsonVercel deploy target

Read package.json to extract:

  • Package manager (packageManager field, or check for pnpm-lock.yaml, yarn.lock, bun.lockb, package-lock.json)
  • Scripts available (lint, test, build, typecheck, format)
  • Node version requirements (engines.node)
  • Framework and key dependencies

For Python, read pyproject.toml or requirements.txt to determine Python version and test framework (pytest, unittest).

Step 2: Ask the User

Present the detection results and ask:

  1. Deploy target (if not obvious from vercel.json/railway.toml):

    • Vercel (auto-deploy via git push, or CLI-based)
    • Railway (auto-deploy or CLI)
    • VPS via SSH (rsync + restart)
    • Docker registry (GHCR, Docker Hub, ECR)
    • None (CI only, no deploy)
  2. Environments: Preview on PR + Production on main? Or just main?

  3. Matrix testing: Test across multiple runtime versions? (e.g., Node 20 + 22, Python 3.11 + 3.12)

  4. Additional checks: Security scanning? Dependency audit? Coverage reporting?

Step 3: Generate Workflows

Create .github/workflows/ directory and generate the appropriate workflow files.

Action Versions Reference (current as of 2026)

Always use these versions:

actions/checkout@v6
actions/setup-node@v6
actions/setup-python@v6
actions/cache@v5
docker/setup-buildx-action@v3
docker/login-action@v3
docker/build-push-action@v6
docker/metadata-action@v5

3A: Node.js / Next.js / Frontend Projects

File: .github/workflows/ci.yml

name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: NODE_VERSION
          cache: PACKAGE_MANAGER
      - run: INSTALL_COMMAND
      - run: LINT_COMMAND

  typecheck:
    name: Type Check
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: NODE_VERSION
          cache: PACKAGE_MANAGER
      - run: INSTALL_COMMAND
      - run: TYPECHECK_COMMAND

  test:
    name: Test
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        node-version: [NODE_VERSIONS]
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: ${{ matrix.node-version }}
          cache: PACKAGE_MANAGER
      - run: INSTALL_COMMAND
      - run: TEST_COMMAND

  build:
    name: Build
    runs-on: ubuntu-latest
    needs: [lint, typecheck, test]
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: NODE_VERSION
          cache: PACKAGE_MANAGER
      - run: INSTALL_COMMAND
      - run: BUILD_COMMAND

Package manager install commands:

  • npm: npm ci
  • pnpm: corepack enable && pnpm install --frozen-lockfile
  • yarn: corepack enable && yarn install --immutable
  • bun: bun install --frozen-lockfile

Cache key for setup-node:

  • npm: cache: npm
  • pnpm: cache: pnpm
  • yarn: cache: yarn

For pnpm, add the corepack enable step before install:

- run: corepack enable
- uses: actions/setup-node@v6
  with:
    node-version: NODE_VERSION
    cache: pnpm

If the project has no test script, omit the test job. If no lint script, omit lint. Same for typecheck. Always keep build.

3B: Python Projects

File: .github/workflows/ci.yml

name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-python@v6
        with:
          python-version: PYTHON_VERSION
          cache: pip
      - run: pip install ruff
      - run: ruff check .

  test:
    name: Test
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        python-version: [PYTHON_VERSIONS]
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python-version }}
          cache: pip
      - run: pip install -r requirements.txt
      - run: pytest

  build:
    name: Build
    runs-on: ubuntu-latest
    needs: [lint, test]
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-python@v6
        with:
          python-version: PYTHON_VERSION
          cache: pip
      - run: pip install -r requirements.txt
      - run: python3 -m build

For pyproject.toml projects, replace pip install -r requirements.txt with pip install -e ".[dev]" or the appropriate extras.

For poetry projects:

- run: pip install poetry
- run: poetry install
- run: poetry run pytest

3C: Docker Projects

File: .github/workflows/docker.yml

name: Docker

on:
  push:
    branches: [main]
    tags: ['v*']
  pull_request:
    branches: [main]

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-push:
    name: Build & Push
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v6

      - uses: docker/setup-buildx-action@v3

      - uses: docker/login-action@v3
        if: github.event_name != 'pull_request'
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - uses: docker/metadata-action@v5
        id: meta
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=sha

      - uses: docker/build-push-action@v6
        with:
          context: .
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

For Docker Hub instead of GHCR:

env:
  REGISTRY: docker.io
  IMAGE_NAME: DOCKER_HUB_USERNAME/IMAGE_NAME

# Login step:
- uses: docker/login-action@v3
  with:
    username: ${{ secrets.DOCKERHUB_USERNAME }}
    password: ${{ secrets.DOCKERHUB_TOKEN }}

For ECR:

- uses: aws-actions/configure-aws-credentials@v4
  with:
    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    aws-region: AWS_REGION
- uses: aws-actions/amazon-ecr-login@v2

3D: Monorepo Projects

For monorepos (Turborepo, pnpm workspaces, Nx), add path filters to avoid running everything on every change:

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  changes:
    name: Detect Changes
    runs-on: ubuntu-latest
    outputs:
      app: ${{ steps.filter.outputs.app }}
      api: ${{ steps.filter.outputs.api }}
      packages: ${{ steps.filter.outputs.packages }}
    steps:
      - uses: actions/checkout@v6
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            app:
              - 'apps/web/**'
              - 'packages/**'
            api:
              - 'apps/api/**'
              - 'packages/**'
            packages:
              - 'packages/**'

  ci-app:
    name: CI (Web)
    needs: changes
    if: needs.changes.outputs.app == 'true'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - run: corepack enable
      - uses: actions/setup-node@v6
        with:
          node-version: NODE_VERSION
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm --filter web lint
      - run: pnpm --filter web test
      - run: pnpm --filter web build

  ci-api:
    name: CI (API)
    needs: changes
    if: needs.changes.outputs.api == 'true'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - run: corepack enable
      - uses: actions/setup-node@v6
        with:
          node-version: NODE_VERSION
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm --filter api lint
      - run: pnpm --filter api test
      - run: pnpm --filter api build

Adapt the app names and filter paths based on the actual monorepo structure. Read pnpm-workspace.yaml or turbo.json to discover workspace packages.

For Turborepo specifically, leverage turbo run:

- run: pnpm turbo run lint test build --filter=...[origin/main]

Step 4: Generate Deploy Workflows

Vercel Deploy

If deploying via Vercel CLI (not git-push auto-deploy):

File: .github/workflows/deploy.yml

name: Deploy

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

concurrency:
  group: deploy-${{ github.ref }}
  cancel-in-progress: true

env:
  VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
  VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

jobs:
  deploy-preview:
    name: Deploy Preview
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    needs: [ci]  # reference CI job
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: NODE_VERSION
          cache: PACKAGE_MANAGER
      - run: npm i -g vercel
      - run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
      - run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
      - run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}

  deploy-production:
    name: Deploy Production
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    runs-on: ubuntu-latest
    needs: [ci]
    environment: production
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: NODE_VERSION
          cache: PACKAGE_MANAGER
      - run: npm i -g vercel
      - run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
      - run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
      - run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}

Required secrets: VERCEL_TOKEN, VERCEL_ORG_ID, VERCEL_PROJECT_ID

If the project uses Vercel's git integration (auto-deploy on push), skip this workflow and tell the user -- CI workflow alone is sufficient since Vercel handles deploys automatically.

Railway Deploy

File: .github/workflows/deploy.yml

name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    name: Deploy to Railway
    runs-on: ubuntu-latest
    needs: [ci]
    environment: production
    steps:
      - uses: actions/checkout@v6
      - uses: npm i -g @railway/cli
      - run: railway up --service SERVICE_NAME
        env:
          RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}

Required secrets: RAILWAY_TOKEN

If Railway auto-deploys from GitHub, tell the user to enable "Wait for CI" in Railway service settings so it waits for the CI workflow to pass before deploying.

VPS via SSH

File: .github/workflows/deploy.yml

name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    name: Deploy to VPS
    runs-on: ubuntu-latest
    needs: [ci]
    environment: production
    steps:
      - uses: actions/checkout@v6

      - name: Deploy via SSH
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          port: ${{ secrets.VPS_PORT }}
          script: |
            cd /path/to/app
            git pull origin main
            INSTALL_AND_BUILD_COMMANDS
            RESTART_COMMAND

For rsync-based deploys (push built artifacts):

      - name: Build
        run: BUILD_COMMAND

      - name: Deploy via rsync
        uses: burnett01/rsync-deployments@7
        with:
          switches: -avzr --delete
          path: dist/
          remote_path: /var/www/app/
          remote_host: ${{ secrets.VPS_HOST }}
          remote_user: ${{ secrets.VPS_USER }}
          remote_key: ${{ secrets.VPS_SSH_KEY }}
          remote_port: ${{ secrets.VPS_PORT }}

      - name: Restart service
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          port: ${{ secrets.VPS_PORT }}
          script: sudo systemctl restart APP_SERVICE

Required secrets: VPS_HOST, VPS_USER, VPS_SSH_KEY, VPS_PORT

Docker Registry Deploy

Use the Docker workflow from Step 3C. If deploying to a server after push, add a post-push job:

  deploy:
    name: Deploy
    needs: build-and-push
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          script: |
            docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main
            docker compose up -d

Step 5: Secrets Checklist

After generating workflows, output a checklist of secrets the user needs to configure in GitHub repo settings (Settings > Secrets and variables > Actions):

Required GitHub Secrets:
- [ ] VERCEL_TOKEN — from vercel.com/account/tokens
- [ ] VERCEL_ORG_ID — from .vercel/project.json or vercel.com dashboard
- [ ] VERCEL_PROJECT_ID — from .vercel/project.json or vercel.com dashboard
- [ ] RAILWAY_TOKEN — from railway.app dashboard > project > settings
- [ ] VPS_HOST — server IP or hostname
- [ ] VPS_USER — SSH username
- [ ] VPS_SSH_KEY — private SSH key (ed25519 recommended)
- [ ] VPS_PORT — SSH port (default 22)
- [ ] DOCKERHUB_USERNAME — Docker Hub username
- [ ] DOCKERHUB_TOKEN — Docker Hub access token

Only list secrets relevant to the chosen deploy target.

Step 6: Status Badge

Offer to add a CI status badge to the project README:

![CI](https://github.com/OWNER/REPO/actions/workflows/ci.yml/badge.svg)

Read the git remote to determine OWNER/REPO automatically:

git remote get-url origin

Rules

  1. Never hardcode secrets. Always use ${{ secrets.NAME }} references.
  2. Always use concurrency groups to cancel redundant runs on the same branch/PR.
  3. Always pin action versions to major tags (e.g., @v6), never @latest or @main.
  4. Use fail-fast: false in matrix builds so one version failing doesn't cancel others.
  5. Separate CI from deploy. CI runs on PRs and pushes. Deploy only runs on main (or tags).
  6. Use GitHub Environments for production deploys to enable approval gates and env-specific secrets.
  7. Cache aggressively. Use setup-node/setup-python built-in cache for dependencies. Use GHA cache for Docker layers.
  8. Run lint/typecheck/test in parallel as separate jobs for faster feedback. Build depends on all passing.
  9. For monorepos, always add path filters. Never run all workspace CI on every file change.
  10. If workflows already exist (.github/workflows/ is non-empty), read them first and ask the user whether to replace or extend.
  11. Replace placeholder values (NODE_VERSION, PACKAGE_MANAGER, etc.) with actual detected values from the project. Never leave placeholders in the generated output.
  12. Only include jobs that the project supports. If there is no test script, no test job. If there is no lint script, no lint job. Don't generate dead jobs.

Comments

Loading comments...