$npx -y skills add datarobot-oss/datarobot-agent-skills --skill datarobot-app-framework-cicdGuidance for setting up CI/CD pipelines for DataRobot application templates using GitLab, GitHub Actions, and Pulumi for infrastructure as code. Use when setting up CI/CD pipelines, configuring deployments, or managing infrastructure for DataRobot application templates.
| 1 | # DataRobot Application Templates CI/CD Skill |
| 2 | |
| 3 | This skill provides comprehensive guidance for setting up production-grade CI/CD pipelines for DataRobot application templates, including automated testing, review deployments, and continuous delivery. |
| 4 | |
| 5 | ## Quick Start |
| 6 | |
| 7 | **Default behavior:** When a user asks to "set up CI/CD" without specifying a platform or backend, always use the [Simple Path](#simple-path-pulumi-cloud--github-secrets) below — three workflow files, two GitHub Secrets, done. Do not create `infra/scripts/`, do not add CI/CD tasks to `infra/Taskfile.yaml`, do not involve GPG encryption unless the user explicitly asks for it. |
| 8 | |
| 9 | Only deviate from the simple path when the user specifies: |
| 10 | - A specific Pulumi state backend (Azure Blob, S3, GCS) → use `scripts/` and see [Implementation Pattern](#implementation-pattern) |
| 11 | - GitLab CI/CD → see [GitLab CI/CD Configuration](#gitlab-cicd-configuration) |
| 12 | - Many secrets to manage → consider GPG approach in `scripts/` |
| 13 | |
| 14 | ## Simple Path: Pulumi Cloud + GitHub Secrets |
| 15 | |
| 16 | For most data scientists and AI engineers, this is all you need. No GPG encryption, no cloud storage account, no extra scripts. |
| 17 | |
| 18 | **What to create in the user's repository:** |
| 19 | |
| 20 | 1. Copy the three workflow files to `.github/workflows/`: |
| 21 | |
| 22 | | Source | Destination | Trigger | |
| 23 | |--------|-------------|---------| |
| 24 | | `examples/github-cd-pulumi-cloud.yml` | `.github/workflows/cd.yml` | Automatic — every merge to `main` | |
| 25 | | `examples/github-deploy-pulumi-cloud.yml` | `.github/workflows/deploy-pr.yml` | Manual — user picks PR branch + enters stack name (e.g. `pr-42`) | |
| 26 | | `examples/github-destroy-pulumi-cloud.yml` | `.github/workflows/destroy.yml` | Manual — user enters stack name to tear down | |
| 27 | |
| 28 | 2. Create `.github/workflows/README.md` from `examples/workflows-README.md`. This is the setup guide that tells the user exactly what secrets and variables to add and how. |
| 29 | |
| 30 | 3. Tell the user to follow the setup guide in `.github/workflows/README.md`. |
| 31 | |
| 32 | That's it. Do **not** add anything to `infra/Taskfile.yaml` or create `infra/scripts/` for this path. |
| 33 | |
| 34 | **Required GitHub Secrets** (both required — no defaults): |
| 35 | |
| 36 | | Name | Kind | |
| 37 | |------|------| |
| 38 | | `DATAROBOT_API_TOKEN` | Secret | |
| 39 | | `PULUMI_ACCESS_TOKEN` | Secret | |
| 40 | |
| 41 | **Optional GitHub Variable** (defaults to `ci` if not set): |
| 42 | |
| 43 | | Name | Kind | Default | |
| 44 | |------|------|---------| |
| 45 | | `PULUMI_STACK_CI_NAME` | Variable | `ci` | |
| 46 | |
| 47 | **When to use the advanced approach (GPG + DIY backends) instead:** |
| 48 | - You have many secrets (GPG encrypts all of `.env` behind a single passphrase — only one GitHub Secret needed) |
| 49 | - Your organization prohibits Pulumi Cloud and requires a self-managed backend (Azure Blob / S3 / GCS) |
| 50 | - You need GitLab CI/CD |
| 51 | |
| 52 | The templates and scripts for all of these are in `scripts/` in this skill directory. If the skill has already been propagated to the project's `infra/` directory (common in downstream templates), look in `infra/scripts/` instead. See the [Implementation Pattern](#implementation-pattern) section below for full setup guidance. |
| 53 | |
| 54 | | Scenario | Key files in `scripts/` | |
| 55 | |----------|------------------------| |
| 56 | | Azure Blob / S3 / GCS Pulumi backend | `pulumi-setup.sh`, `taskfile-snippets.yaml` | |
| 57 | | GitHub Actions + GPG secrets | `github-deploy.yml`, `github-cd.yml`, `encrypt-secrets.sh`, `setup-github-secrets.sh` | |
| 58 | | GitLab CI/CD | `gitlab-ci.yml`, `setup-gitlab-variables.sh` | |
| 59 | |
| 60 | ### Adapting the deploy command |
| 61 | |
| 62 | The example workflows use `uv run pulumi up --yes` directly. Before copying them, check `infra/Taskfile.yaml` — the project may already wrap the deploy command in a task: |
| 63 | |
| 64 | ```bash |
| 65 | cat infra/Taskfile.yaml # look for 'up-yes', 'deploy', or similar tasks |
| 66 | ``` |
| 67 | |
| 68 | | What you find | What to use in CI | |
| 69 | |---------------|-------------------| |
| 70 | | `up-yes` task | `task up-yes` — non-interactive, purpose-built for CI; prefer this over raw Pulumi | |
| 71 | | `deploy` task (alias for `up`) | Avoid — typically runs `pulumi up` interactively; only safe in CI if you confirm it passes `-y` internally | |
| 72 | | No Taskfile or no relevant task | Keep `uv run pulumi up --yes` as-is | |
| 73 | |
| 74 | To use `task` in a workflow, add an install step and swap the run command: |
| 75 | |
| 76 | ```yaml |
| 77 | - name: Install Task |
| 78 | run: pip install go-task-bin |
| 79 | |
| 80 | - name: Deploy |
| 81 | working-directory: infra |
| 82 | env: |
| 83 | DATAROBOT_API_TOKEN: ${{ secrets.DATAROBOT_API_TOKEN }} |
| 84 | PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }} |
| 85 | run: | |
| 86 | uv sync --all-extras |
| 87 | task up-yes |
| 88 | ``` |
| 89 | |
| 90 | ### DataRobot API token (service account) |
| 91 | |
| 92 | `DATAROBOT_API_TOKEN` should come from a **DataRobot service account** — a DataRobot user created for a |