Design CI/CD, environments and release flow for AEM as a Cloud Service with Cloud Manager — pipeline types, quality gates, Maven build rules, Git setup, env vars and secrets, RDEs, local SDK, logs, repoinit and index deployment.
When agents use itUse this whenever the user sets up or debugs a Cloud Manager pipeline; sees a failed code quality, build or deploy step; asks about full-stack vs front-end vs web-tier vs config pipelines, dev/stage/prod or Rapid Development Environments, `aio aem:rde install`, the AEM SDK quickstart or dispatcher SDK, `.cloudmanager/java-version`, the `all` package, filter.xml, runmodes, `$[env:]`/`$[secret:]` OSGi values, repoinit scripts, custom oak indexes, log forwarding, CDN config.yaml, branch strategy, rollback or AEM release updates. Also use it when planning a go-live release checklist, even if they only ask why one pipeline step failed.
Install
Copilot (VS Code, Visual Studio, Copilot CLI and github.com) reads skills from the repository — commit them so the whole team gets them.
npx skills add AGCO-Global/org-skills --skill aem-cloud-manager -a github-copilot
# or with the org installer (adds .github/skills/aem-cloud-manager):
npx -y github:AGCO-Global/org-skills add skill aem-cloud-manager
Uses the open skills CLI. Works with Claude Code, Codex, Cursor, Copilot, Gemini CLI, OpenCode, Windsurf and 60+ others — it asks which agent to install into.
Installs the aem-devops-skills plugin, which bundles all AEM / DevOps skills and keeps them updated.
/plugin marketplace add AGCO-Global/org-skills
/plugin install aem-devops-skills@org-skills
# or just this skill, in this repository:
npx skills add AGCO-Global/org-skills --skill aem-cloud-manager -a claude-code
Use Download .zip above, then upload it under Customize → Skills → Upload skill. Team and Enterprise admins can sync this repo as a plugin marketplace instead.
Installs into .agents/skills/, which Codex reads.
npx skills add AGCO-Global/org-skills --skill aem-cloud-manager -a codex
Installs into Cursor's skills folder.
npx skills add AGCO-Global/org-skills --skill aem-cloud-manager -a cursor
Installs into Gemini CLI's skills folder.
npx skills add AGCO-Global/org-skills --skill aem-cloud-manager -a gemini-cli
Any tool with rules, instructions or custom prompts: use Copy SKILL.md above and paste it in. It is plain Markdown.
Commands use your normal git sign-in to GitHub, so they work while the repository is private. Node.js 20+ required.
Skill contents
AEM Cloud Manager CI/CD
Cloud Manager is the only road to stage and prod: it builds from Git, gates on quality rules, deploys blue-green, and never rolls back content. Design every change so it passes the gates on the first try, is repeatable from a Git tag, and is safe to redeploy.
Keep the SDK version close to the cloud release; it is not a full replica (no CDN, no asset microservices)
RDE (Rapid Development Environment)
Seconds-to-minutes iteration on bundles, packages, OSGi configs, dispatcher config
Deploy via aio CLI, not pipelines; reset often; not for performance or integration sign-off
Dev
Integration of merged work, author testing, API integrations
Non-production pipeline; may hibernate on sandbox programs
Stage
Release candidate validation, UAT, load testing
Deployed only by the production pipeline; mirror prod config
Prod
Live
Deployed only after stage passes and approval
Program types: sandbox programs are for trials and learning (hibernation, limited features); production programs carry SLAs. Verify the current entitlement details in Adobe docs before promising features.
Theme/JS/CSS built by npm run build from a front-end module
Sites using site themes; decouples FE release cadence
Web-tier config
Dispatcher configuration only
Frequent dispatcher/rewrite changes; requires flexible mode. Once it exists, the full-stack pipeline stops deploying dispatcher config for that environment
Config pipeline
YAML config (e.g. CDN rules, traffic filters, log forwarding, other supported kinds) from a config/ folder
Edge and platform config that doesn't need a code build; check current docs for supported kinds
Code quality only
Nothing; runs scans
Feature branches and PR validation
Production vs non-production: the production pipeline deploys to stage then prod; non-production pipelines target dev (or run quality only). Triggers: manual, or on Git commit for dev.
3. Production pipeline stages and gates
Build & unit tests — Maven build in Cloud Manager's image; unit test failures stop the pipeline.
Code scanning — SonarQube-based rules plus AEM-specific rules (Cloud Service compatibility, OakPAL content-package checks such as immutable/mutable mixing, index definitions).
Build images — assembles your code with the current AEM release.
Stage deploy — blue-green; failure leaves the old version serving.
Approval / schedule — optional manual approval by business owner; schedule the prod deploy.
Prod deploy — blue-green.
Gate levels: critical failures stop the pipeline; important failures pause it and an authorised role can override; info is reported only. Typical metrics include security, reliability and maintainability ratings, unit test coverage (commonly a 50% threshold), skipped tests, open issues and duplication. Check the current thresholds in Adobe docs — they change.
Never "override and move on" for security or Cloud Service compatibility findings; fix them or record a dated exception.
4. Git setup
Adobe-managed repo: Cloud Manager builds from it. Mirror from your team's Git with a CI job that pushes main/develop and tags.
Private / bring-your-own repo (GitHub and, per current docs, other providers): link the repo in Cloud Manager, install the app/credentials, and get PR-level code quality checks. Prefer this when available — it removes mirroring drift.
One Cloud Manager repo per program is simplest; multiple repos need a clear owner per pipeline.
Protect main: PR review + local build (mvn clean install) + code quality pipeline green before merge.
5. Maven build requirements
Java version: select via .cloudmanager/java-version (e.g. 21 or 11, per currently supported versions); compile target must match what the AEM release runs.
The all package embeds every deployable into /apps/<project>-packages/{application,content}/install[.<runmode>]. Anything not embedded is not deployed.
Package types (filevault-package-maven-plugin): application for /apps, content for mutable paths, container for all. mixed fails the gates.
filter.xml: narrow roots; mode="merge" or update for content you seed but authors own; never a bare /content root with default replace.
Repositories: third-party artifacts must come from reachable repos; use password-protected repos via pipeline variables, never committed credentials.
Versioning: SNAPSHOTs are acceptable in the build; tag releases in Git so any prod state is reproducible.
6. Configuration, runmodes, secrets
Runmodes available: author, publish, dev, stage, prod, rde, and combinations (config.author.prod). Custom runmodes are not supported — use env vars instead.
OSGi configs are .cfg.json in ui.config under /apps/<project>/osgiconfig/config.<runmode>/.
Environment-specific values via Cloud Manager environment variables; sensitive values as secret type:
Build-time values (private repo credentials, npm tokens) are pipeline variables, not environment variables.
Changing an env var restarts services on that environment — batch changes, don't toggle on prod during peak.
7. Repoinit, indexes and service users
Create service users, ACLs, and structural folders with repoinit in an OSGi factory config, not with content packages:
{
"scripts": [
"create service user project-content-reader with path system/project",
"set ACL for project-content-reader\n allow jcr:read on /content/project\nend",
"create path (sling:Folder) /conf/project/settings"
]
}
Map service users with org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~project.cfg.json.
Custom indexes live in ui.apps under /oak:index with versioned names (<name>-custom-<n> for new ones, <oob-name>-<version>-custom-<n> for customised product indexes). Bump the number on every change; include them in filter.xml; expect long reindex times on large repos and deploy early in the release.
Verify flags against the plugin's current --help. RDE state is not a source of truth — every change must still go through Git and a pipeline.
9. Local development with the SDK
Quickstart: rename the jar to aem-author-p4502.jar / aem-publish-p4503.jar and run it; install the all package with mvn clean install -PautoInstallSinglePackage.
Dispatcher SDK: validate with bin/validate.sh src, run with bin/docker_run.sh src host.docker.internal:4503 8080. Validation that fails locally will fail in the pipeline.
Keep aem-sdk-api in the parent POM aligned with the SDK and the cloud release.
10. Logs, releases, rollback
Logs: download or tail from Cloud Manager (or aio cloudmanager:tail-log); forward to your SIEM/observability tool via the log forwarding config. Log at INFO in prod for your packages; DEBUG only on dev/RDE.
AEM releases: Adobe applies maintenance updates automatically; your pipeline is blocked while one runs. Keep builds green on the latest SDK — a failing custom functional test blocks product updates.
Rollback: there is no rollback button. A failed deploy leaves the previous version serving; to revert a successful deploy, redeploy the previous Git tag. Content changed by packages or by authors is not reverted — plan content migrations as forward-only, idempotent steps.
11. Branch strategy and release flow
feature/* → PR → code quality pipeline + RDE for demo
develop → dev pipeline (auto on commit)
release/x → stage via prod pipeline, UAT, fix-forward
main + tag → prod pipeline, approval, scheduled deploy
hotfix/* → from tag, merged back to main and develop
Deliverable format
## Pipeline design
Repo: <Adobe-managed | BYO provider> Java: <version> Structure: <modules>
| Pipeline | Type | Branch | Trigger | Target env | Gates overridden? |
Env vars/secrets: <name → purpose, env scope, secret?>
Runmode configs: <list of config.<runmode> folders>
## Release checklist
- [ ] Local build + dispatcher validate green on current SDK
- [ ] Code quality: 0 critical, importants fixed or documented
- [ ] Index changes versioned and deployed ahead of dependent code
- [ ] Repoinit covers new service users/ACLs; no user content in packages
- [ ] Env vars/secrets created on stage and prod before deploy
- [ ] Stage tests + experience audit reviewed; UAT sign-off
- [ ] Prod deploy scheduled outside peak; rollback = redeploy tag <x>
- [ ] Post-deploy smoke + log check
Anti-patterns to reject
Mixed packages (/apps and /content in one package) or content packages without a narrow filter.
Custom runmodes, or secrets hardcoded in .cfg.json or committed settings.xml.
Service users and ACLs shipped as content packages instead of repoinit.
Changing an existing index definition without bumping its version suffix.
Overriding important security/compatibility failures to hit a date.
Treating RDE or dev as the source of truth; hotfixing prod config outside Git.
Assuming a redeploy reverts content changes; non-idempotent content migrations.
Letting the local SDK drift many releases behind the cloud environment.
---
name: aem-cloud-manager
description: Design CI/CD, environments and release flow for AEM as a Cloud Service with Cloud Manager — pipeline types, quality gates, Maven build rules, Git setup, env vars and secrets, RDEs, local SDK, logs, repoinit and index deployment. Use this whenever the user sets up or debugs a Cloud Manager pipeline; sees a failed code quality, build or deploy step; asks about full-stack vs front-end vs web-tier vs config pipelines, dev/stage/prod or Rapid Development Environments, `aio aem:rde install`, the AEM SDK quickstart or dispatcher SDK, `.cloudmanager/java-version`, the `all` package, filter.xml, runmodes, `$[env:]`/`$[secret:]` OSGi values, repoinit scripts, custom oak indexes, log forwarding, CDN config.yaml, branch strategy, rollback or AEM release updates. Also use it when planning a go-live release checklist, even if they only ask why one pipeline step failed.
metadata:
technology: AEM
type: devops
---
# AEM Cloud Manager CI/CD
Cloud Manager is the only road to stage and prod: it builds from Git, gates on quality rules, deploys blue-green, and never rolls back content. Design every change so it passes the gates on the first try, is repeatable from a Git tag, and is safe to redeploy.
## 1. Environments — pick the right one for the job
| Environment | Use for | Notes |
|---|---|---|
| Local AEM SDK (quickstart + dispatcher SDK) | Daily development, unit/IT tests, dispatcher validation | Keep the SDK version close to the cloud release; it is not a full replica (no CDN, no asset microservices) |
| **RDE** (Rapid Development Environment) | Seconds-to-minutes iteration on bundles, packages, OSGi configs, dispatcher config | Deploy via `aio` CLI, not pipelines; reset often; not for performance or integration sign-off |
| Dev | Integration of merged work, author testing, API integrations | Non-production pipeline; may hibernate on sandbox programs |
| Stage | Release candidate validation, UAT, load testing | Deployed only by the production pipeline; mirror prod config |
| Prod | Live | Deployed only after stage passes and approval |
Program types: sandbox programs are for trials and learning (hibernation, limited features); production programs carry SLAs. Verify the current entitlement details in Adobe docs before promising features.
## 2. Pipeline types
| Pipeline | Deploys | When to use |
|---|---|---|
| **Full-stack** | Code + content packages + (optionally) dispatcher config | Default; every Java/HTL/config change |
| **Front-end** | Theme/JS/CSS built by `npm run build` from a front-end module | Sites using site themes; decouples FE release cadence |
| **Web-tier config** | Dispatcher configuration only | Frequent dispatcher/rewrite changes; requires flexible mode. Once it exists, the full-stack pipeline stops deploying dispatcher config for that environment |
| **Config pipeline** | YAML config (e.g. CDN rules, traffic filters, log forwarding, other supported kinds) from a `config/` folder | Edge and platform config that doesn't need a code build; check current docs for supported `kind`s |
| Code quality only | Nothing; runs scans | Feature branches and PR validation |
Production vs non-production: the **production** pipeline deploys to stage then prod; **non-production** pipelines target dev (or run quality only). Triggers: manual, or on Git commit for dev.
## 3. Production pipeline stages and gates
1. **Build & unit tests** — Maven build in Cloud Manager's image; unit test failures stop the pipeline.
2. **Code scanning** — SonarQube-based rules plus AEM-specific rules (Cloud Service compatibility, OakPAL content-package checks such as immutable/mutable mixing, index definitions).
3. **Build images** — assembles your code with the current AEM release.
4. **Stage deploy** — blue-green; failure leaves the old version serving.
5. **Stage testing** — product functional tests, custom functional tests (`it.tests`), custom UI tests (`ui.tests`), experience audit (Lighthouse-based page scoring on configured paths).
6. **Approval / schedule** — optional manual approval by business owner; schedule the prod deploy.
7. **Prod deploy** — blue-green.
Gate levels: **critical** failures stop the pipeline; **important** failures pause it and an authorised role can override; **info** is reported only. Typical metrics include security, reliability and maintainability ratings, unit test coverage (commonly a 50% threshold), skipped tests, open issues and duplication. Check the current thresholds in Adobe docs — they change.
Never "override and move on" for security or Cloud Service compatibility findings; fix them or record a dated exception.
## 4. Git setup
- **Adobe-managed repo**: Cloud Manager builds from it. Mirror from your team's Git with a CI job that pushes `main`/`develop` and tags.
- **Private / bring-your-own repo** (GitHub and, per current docs, other providers): link the repo in Cloud Manager, install the app/credentials, and get PR-level code quality checks. Prefer this when available — it removes mirroring drift.
- One Cloud Manager repo per program is simplest; multiple repos need a clear owner per pipeline.
- Protect `main`: PR review + local build (`mvn clean install`) + code quality pipeline green before merge.
## 5. Maven build requirements
- **Java version**: select via `.cloudmanager/java-version` (e.g. `21` or `11`, per currently supported versions); compile target must match what the AEM release runs.
- **Structure** (AEM Project Archetype): `core` (bundle), `ui.apps` (immutable `/apps`), `ui.config` (OSGi configs), `ui.content` (mutable `/content`, `/conf`), `ui.frontend`, `dispatcher`, `all` (container), `it.tests`, `ui.tests`.
- The **`all` package embeds** every deployable into `/apps/<project>-packages/{application,content}/install[.<runmode>]`. Anything not embedded is not deployed.
- **Package types** (`filevault-package-maven-plugin`): `application` for `/apps`, `content` for mutable paths, `container` for `all`. `mixed` fails the gates.
- **filter.xml**: narrow roots; `mode="merge"` or `update` for content you seed but authors own; never a bare `/content` root with default replace.
- Repositories: third-party artifacts must come from reachable repos; use password-protected repos via pipeline variables, never committed credentials.
- Versioning: SNAPSHOTs are acceptable in the build; tag releases in Git so any prod state is reproducible.
## 6. Configuration, runmodes, secrets
- Runmodes available: `author`, `publish`, `dev`, `stage`, `prod`, `rde`, and combinations (`config.author.prod`). Custom runmodes are not supported — use env vars instead.
- OSGi configs are `.cfg.json` in `ui.config` under `/apps/<project>/osgiconfig/config.<runmode>/`.
- Environment-specific values via Cloud Manager **environment variables**; sensitive values as **secret** type:
```json
{
"apiEndpoint": "$[env:PARTNER_API_URL;default=https://sandbox.example.com]",
"apiKey": "$[secret:PARTNER_API_KEY]"
}
```
- Build-time values (private repo credentials, npm tokens) are **pipeline variables**, not environment variables.
- Changing an env var restarts services on that environment — batch changes, don't toggle on prod during peak.
## 7. Repoinit, indexes and service users
- Create service users, ACLs, and structural folders with **repoinit** in an OSGi factory config, not with content packages:
```json
{
"scripts": [
"create service user project-content-reader with path system/project",
"set ACL for project-content-reader\n allow jcr:read on /content/project\nend",
"create path (sling:Folder) /conf/project/settings"
]
}
```
- Map service users with `org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~project.cfg.json`.
- **Custom indexes** live in `ui.apps` under `/oak:index` with versioned names (`<name>-custom-<n>` for new ones, `<oob-name>-<version>-custom-<n>` for customised product indexes). Bump the number on every change; include them in `filter.xml`; expect long reindex times on large repos and deploy early in the release.
## 8. Fast iteration with RDE
```bash
aio plugins:install @adobe/aio-cli-plugin-aem-rde
aio aem:rde:setup # choose program/environment
aio aem:rde:install all/target/project.all-1.0.0-SNAPSHOT.zip
aio aem:rde:install core/target/project.core-1.0.0-SNAPSHOT.jar
aio aem:rde:install -t dispatcher-config dispatcher/target/dispatcher.zip
aio aem:rde:status # what's deployed
aio aem:rde:reset # back to clean state
```
Verify flags against the plugin's current `--help`. RDE state is not a source of truth — every change must still go through Git and a pipeline.
## 9. Local development with the SDK
- Quickstart: rename the jar to `aem-author-p4502.jar` / `aem-publish-p4503.jar` and run it; install the `all` package with `mvn clean install -PautoInstallSinglePackage`.
- Dispatcher SDK: validate with `bin/validate.sh src`, run with `bin/docker_run.sh src host.docker.internal:4503 8080`. Validation that fails locally will fail in the pipeline.
- Keep `aem-sdk-api` in the parent POM aligned with the SDK and the cloud release.
## 10. Logs, releases, rollback
- **Logs**: download or tail from Cloud Manager (or `aio cloudmanager:tail-log`); forward to your SIEM/observability tool via the log forwarding config. Log at `INFO` in prod for your packages; `DEBUG` only on dev/RDE.
- **AEM releases**: Adobe applies maintenance updates automatically; your pipeline is blocked while one runs. Keep builds green on the latest SDK — a failing custom functional test blocks product updates.
- **Rollback**: there is no rollback button. A failed deploy leaves the previous version serving; to revert a successful deploy, redeploy the previous Git tag. Content changed by packages or by authors is **not** reverted — plan content migrations as forward-only, idempotent steps.
## 11. Branch strategy and release flow
```
feature/* → PR → code quality pipeline + RDE for demo
develop → dev pipeline (auto on commit)
release/x → stage via prod pipeline, UAT, fix-forward
main + tag → prod pipeline, approval, scheduled deploy
hotfix/* → from tag, merged back to main and develop
```
## Deliverable format
```
## Pipeline design
Repo: <Adobe-managed | BYO provider> Java: <version> Structure: <modules>
| Pipeline | Type | Branch | Trigger | Target env | Gates overridden? |
Env vars/secrets: <name → purpose, env scope, secret?>
Runmode configs: <list of config.<runmode> folders>
## Release checklist
- [ ] Local build + dispatcher validate green on current SDK
- [ ] Code quality: 0 critical, importants fixed or documented
- [ ] Index changes versioned and deployed ahead of dependent code
- [ ] Repoinit covers new service users/ACLs; no user content in packages
- [ ] Env vars/secrets created on stage and prod before deploy
- [ ] Stage tests + experience audit reviewed; UAT sign-off
- [ ] Prod deploy scheduled outside peak; rollback = redeploy tag <x>
- [ ] Post-deploy smoke + log check
```
## Anti-patterns to reject
- Mixed packages (`/apps` and `/content` in one package) or content packages without a narrow filter.
- Custom runmodes, or secrets hardcoded in `.cfg.json` or committed `settings.xml`.
- Service users and ACLs shipped as content packages instead of repoinit.
- Changing an existing index definition without bumping its version suffix.
- Overriding important security/compatibility failures to hit a date.
- Treating RDE or dev as the source of truth; hotfixing prod config outside Git.
- Assuming a redeploy reverts content changes; non-idempotent content migrations.
- Letting the local SDK drift many releases behind the cloud environment.