with one click
devops
CI/CD, deployment, infrastructure, and environment configuration.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
CI/CD, deployment, infrastructure, and environment configuration.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
| name | devops |
| description | CI/CD, deployment, infrastructure, and environment configuration. |
| version | 1.0.0 |
| author | Hermes Coder (adapted from Squad network/inco) |
| license | MIT |
| platforms | ["linux","macos","windows"] |
| metadata | {"hermes":{"tags":["cicd","deployment","infrastructure","docker","github-actions"],"related_skills":["architect","security","implementer"]}} |
Apply this lens when evaluating CI/CD changes, deployment configurations, or infrastructure concerns.
Identity: DevOps engineer responsible for build, deploy, and infrastructure reliability.
Expertise:
Responsibilities:
When dispatching DevOps tasks (see active harness skill for exact command syntax):
<files>. Ensure: builds are reproducible, tests run in CI, secrets are properly managed."When designing or updating automated cron jobs, background runners, or daily scripts/notifications:
/dev/null and output a single, high-level status line (e.g., Backup completed successfully at TIMESTAMP).No changes detected. Backup skipped.) to avoid spamming the user with long empty logs or unnecessary text.When hardening containers in multi-service configurations, healthchecks provide essential orchestration signals (enabling correct startup order). However, minimal base images (such as python:slim or alpine) often exclude curl or wget.
Python-Slim Images: Avoid adding unnecessary packages. Execute a standard library Python one-liner to perform HTTP checks:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
Nginx/Alpine Images: Use the native busybox wget for quick HTML root verification:
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3000/ || exit 1"]
Dependency Gating: Configure the reverse proxy/frontend port mapping to bind only to loopback (127.0.0.1:<port>) in development, and use depends_on to gate frontend boot on the API being healthy:
depends_on:
backend:
condition: service_healthy
When introducing automated CI/CD checks (such as GitHub Actions) to existing legacy codebases, strict linter checks often fail on non-breaking files (e.g., pedantic style choices or unused imports).
eslint.config.js to treat styling, refresh, or context rules as 'warn' instead of 'error'. This allows build checking (npm run build targeting tsc -b && vite build) to act as the primary compile gate.--ignore E402 in the CI CLI invocation if standard files perform inline warnings/warnings suppressions before module imports. This prevents required order-suppressions from failing the pipeline.backend/.venv via uv sync --directory backend), executing uv run ruff check at the repository root in CI will fail to find ruff with a "No such file or directory (os error 2)" error. Always configure the linter step to run with the correct working-directory: <sub-folder> (or specify --directory <sub-folder> in uv) to ensure it executes within the correct virtual environment context.package-lock.json for resolved URLs pointing to private Artifact Registries (e.g., us-npm.pkg.dev or Artifactory). Symmetrically replace private URLs with public npm registry equivalents (https://registry.npmjs.org) in the lockfile to unlock public builds.APScheduler or Node's node-cron running inside the app process) will fail or duplicate tasks in serverless environments. Containers scale down to zero when idle, completely wiping out memory-scheduled triggers. Conversely, scaling up to multiple concurrent instances will execute duplicate jobs.
/api/notifications/trigger-deadline gated by a secure pre-shared token header) and configure an external distributed cloud cron scheduler (such as Google Cloud Scheduler or AWS EventBridge) to trigger it.registry.k8s.io), causing silent ImagePullBackOff failures.
agent-sandbox issues where the sandbox-router fails to pull, refer to:
[references/agent-sandbox-router.md](references/agent-sandbox-router.md)[references/gke-autopilot-gateway-troubleshooting.md](references/gke-autopilot-gateway-troubleshooting.md)When introducing pre-deployment container smoke tests in modern CI/CD pipelines (such as Google Cloud Build or equivalent Docker-in-Docker environments), we must navigate container network namespaces and filesystem write privileges:
cloudbuild. Background containers launched with docker run -d within a step are running as sibling containers on the same host. They cannot be accessed via localhost from other steps or within the same step. To enable communication, you must attach your background containers to the shared network using --network cloudbuild and address them directly by their container name (e.g. http://test-backend:8000/api/health and http://test-frontend:8080/).USER appuser) for security compliance. If a smoke-test container boots up and attempts to create or write an in-memory or file-based SQLite database in the default application directory (e.g. ./smoke_test.db in /app, which was populated by root during build), it will crash with sqlite3.OperationalError: unable to open database file. Point DATABASE_URL inside the smoke-test environment to a globally writable directory like /tmp/smoke_test.db (e.g. sqlite:////tmp/smoke_test.db) to ensure successful, permission-safe execution.Running database migrations (such as alembic upgrade head) directly inside your application container's startup command (CMD or entrypoint) is a dangerous production anti-pattern. On Cloud Run (or any serverless platform), scale-ups, cold starts, and multi-instance scaling events will launch multiple concurrent containers, causing migration races, table locking, or database connection pool exhaustion.
uvicorn app.main:app).gcloud run jobs deploy migrate-job --execute-now --wait) before the application's service replacement step. This ensures that:
:$SHORT_SHA), guaranteeing that migration definitions perfectly match the application revision.JWT_SECRET_KEY are changed from their default values when running against a production database dialect), executing Alembic commands inside the container will trigger those validation checks. If those secrets are missing from the job context, the container will immediately exit with a ValidationError / exit(1) before migrations even start. Always bind all necessary production secrets symmetrically (--set-secrets=...) to the migration job's environment context.[references/cloudbuild-migrate-jwt-secret-validation.md](references/cloudbuild-migrate-jwt-secret-validation.md).Avoid using database superuser credentials (such as the default postgres role) inside container environment connections.
DATABASE_URL from separate environmental inputs: postgresql://${DB_USER:-postgres}:${DB_PASSWORD} @ /${DB_NAME:-app_db}?host=${DB_SOCKET_DIR}. This maintains seamless local/development backward-compatibility (falling back safely to standard defaults) while unlocking custom database credentials in production.DB_USER and DB_NAME values (such as app_db) in your service specification YAML files, restricting connection privileges purely to the schema operations required by the runtime application.In open-source or shared repositories with active personal forks, release, deployment, or package-publishing workflows (such as publishing to NuGet, npm, or PyPI) will frequently execute on forks (e.g. on branches pushed to the fork's development branch). Because forks do not inherit OIDC trusted publishing configurations, repository variables, or secrets, these workflows will crash and create false-alarm failure alerts on the fork.
if constraint to the publish or deploy job definition in GitHub Actions:
jobs:
publish:
if: github.repository == 'bradygaster/squad' # Replace with canonical upstream owner/repo
runs-on: ubuntu-latest
To prevent runtime environment drifts and secure immutable rollbacks, avoid referencing the floating latest alias for Secret Manager secrets in production manifests. Instead, resolve and stamp concrete integer versions at deploy time:
key: latest to maintain manual deployability. Add a CI step (e.g. Google Cloud Build using gcloud) that dynamically fetches the latest enabled integer version of each runtime secret:
DB_PASSWORD_VER=$(gcloud secrets versions list db-password --filter='state:enabled' --sort-by=~createTime --limit=1 --format='value(name)')
Then, use a robust Python regex one-liner to perform a targeted in-place edit in the manifest file before deployment without corrupting comments or YAML structure:
python3 -c 'import sys, re; args = {sys.argv[i].lstrip("-").replace("-", "_"): sys.argv[i+1] for i in range(1, len(sys.argv), 2) if i+1 < len(sys.argv)}; content = open("infra/backend-service.yaml").read(); pin = lambda text, name, ver: re.sub(rf"(key:\s*)latest(\s*\n\s*name:\s*{name}\b)", rf"\g<1>{ver}\g<2>", text); [content := pin(content, name.replace("_", "-"), ver) for name, ver in args.items()]; open("infra/backend-service.yaml", "w").write(content)' --db-password "$DB_PASSWORD_VER" --jwt-secret-key "$JWT_SECRET_KEY_VER"
--set-secrets=DB_PASSWORD=db-password:$$DB_PASSWORD_VER).availableSecrets in Cloud Build to populate frontend environment variables during compilation) are resolved at build-trigger initialization—before any build steps run. These are out of scope for deploy-time step pinning and can be left as latest with a clarifying documentation comment.Branch, commit, push, and open PRs with humanized messages, then monitor GitHub Actions CI. Per-project autonomy gating; blocks direct pushes to the default branch and pushes with a dirty tree. Never auto-merges.
Dispatch patterns for Claude Code as the coding engine. Default harness. Implementation dispatches go through dispatch_coder.py (writes the dispatch receipt the commit gate requires).
Testing strategy, TDD enforcement, spec compliance, and regression checks.
Write implementation plans: bite-sized tasks for coding engine dispatch.
Automated fix loop for failed Quality/Reviewer checks. Parses failures, builds escalating prompts, dispatches through the active harness up to 3 times.
Run independent, file-disjoint plan tasks concurrently, each isolated in its own git worktree + branch. Collects per-task results; never auto-merges.