Devops Deploy
sickn33/agentic-awesome-skills
DevOps e deploy de aplicacoes — Docker, CI/CD com GitHub Actions, AWS Lambda, SAM, Terraform, infraestrutura como codigo e monitoramento.
Makes an existing Python recipe deployable: generates the serving files a container needs (Dockerfile, .dockerignore, fastapiapp.py, apputils/a2a.py, apputils/services.py…
$ npx skills add google/adk-recipes --skill make-python-recipe-deployable -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install google/adk-recipes make-python-recipe-deployable --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/google/adk-recipes.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/make-python-recipe-deployable .claude/skills/make-python-recipe-deployable && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "make-python-recipe-deployable" agent skill from https://github.com/google/adk-recipes/tree/main/.agents/skills/make-python-recipe-deployable into .claude/skills/make-python-recipe-deployable/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "make-python-recipe-deployable", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/google/adk-recipes/tree/main/.agents/skills/make-python-recipe-deployableType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add google/adk-recipes --skill make-python-recipe-deployable -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install google/adk-recipes make-python-recipe-deployable --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/google/adk-recipes.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/make-python-recipe-deployable .agents/skills/make-python-recipe-deployable && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "make-python-recipe-deployable" agent skill from https://github.com/google/adk-recipes/tree/main/.agents/skills/make-python-recipe-deployable into .agents/skills/make-python-recipe-deployable/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "make-python-recipe-deployable", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add google/adk-recipes --skill make-python-recipe-deployable -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install google/adk-recipes make-python-recipe-deployable --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/google/adk-recipes.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/make-python-recipe-deployable .cursor/skills/make-python-recipe-deployable && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "make-python-recipe-deployable" agent skill from https://github.com/google/adk-recipes/tree/main/.agents/skills/make-python-recipe-deployable into .cursor/skills/make-python-recipe-deployable/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "make-python-recipe-deployable", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/google/adk-recipes.git --path .agents/skills/make-python-recipe-deployable--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add google/adk-recipes --skill make-python-recipe-deployable -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install google/adk-recipes make-python-recipe-deployable --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/google/adk-recipes.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/make-python-recipe-deployable .gemini/skills/make-python-recipe-deployable && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "make-python-recipe-deployable" agent skill from https://github.com/google/adk-recipes/tree/main/.agents/skills/make-python-recipe-deployable into .gemini/skills/make-python-recipe-deployable/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "make-python-recipe-deployable", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install google/adk-recipes make-python-recipe-deployableInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add google/adk-recipes --skill make-python-recipe-deployable -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/google/adk-recipes.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/make-python-recipe-deployable .github/skills/make-python-recipe-deployable && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "make-python-recipe-deployable" agent skill from https://github.com/google/adk-recipes/tree/main/.agents/skills/make-python-recipe-deployable into .github/skills/make-python-recipe-deployable/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "make-python-recipe-deployable", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add google/adk-recipes --skill make-python-recipe-deployable -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install google/adk-recipes make-python-recipe-deployable --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/google/adk-recipes.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/make-python-recipe-deployable .opencode/skills/make-python-recipe-deployable && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "make-python-recipe-deployable" agent skill from https://github.com/google/adk-recipes/tree/main/.agents/skills/make-python-recipe-deployable into .opencode/skills/make-python-recipe-deployable/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "make-python-recipe-deployable", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
make-python-recipe-deployableMakes an existing Python recipe deployable: generates the serving files a container needs (Dockerfile, .dockerignore, fastapiapp.py, apputils/a2a.py, apputils/services.py…
Make Python Recipe Deployable is an agent skill from google/adk-recipes, published by the product's own GitHub organization. Makes an existing Python recipe deployable: generates the serving files a container needs (Dockerfile, .dockerignore, fastapiapp.py, apputils/a2a.py, apputils/services.py, apputils/reasoningengineadapter.py) and configures the recipe to match (required serving dependencies, the App object in agent.py, the hatch wheel package, manifest.deployable). Interactive by design — it asks the recipe owner about runtime data directories and stops for a human decision when a recipe needs an ADK migration or carries a legacy…
Its SKILL.md is about 6.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 13 other files, including scripts (for example `resources/templates/app_utils/a2a.py`, `resources/templates/app_utils/reasoning_engine_adapter.py` and `resources/templates/app_utils/services.py`).
It sits in DevOps & Cloud, covering Containers and Infrastructure as code. It works with Python, Docker, Terraform and FastAPI. The repository describes itself as: A collection of agent recipes, reference patterns, and vertical plugins built with Agent Development Kit (ADK). The licence is Apache-2.0.
9 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit c339821. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 1 file in scripts/ (Python), which the agent can run.
Shell commands in SKILL.md call:
uvpython3From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use uv, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Make Python Recipe Deployable loads about 6.9k tokens when it runs. Until then it costs about 257 tokens; SKILL.md has 3,465 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check noted patterns worth knowing about, such as sudo or a known installer.
E`, and `.dockerignore` correctly keeps `.env` out of the image.Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from google/adk-recipes at commit c339821, republished under its Apache-2.0 licence (© google). 3,465 words, ~6,921 tokens.
.claude/skills/make-python-recipe-deployable/SKILL.md (or your agent's skills folder). This skill also uses 8 other files; get the full folder from GitHub.A deployable recipe is one that can be packaged into a container and run as a service. This skill writes the files that requires and configures the recipe to match.
It does not build an image, deploy anything, or provision infrastructure. Image builds happen later via Cloud Build → Artifact Registry; this skill's job ends when the files are correct.
The standard it implements lives in .github/policy.yml under deployability:
— the minimum google-adk version, the required dependency list, the required
file list, and the legacy app_utils file list. Change the standard there,
not in the script.
deployable in .github/schemas/manifest-schema.json means "can be deployed
with one click". Two independent questions decide the outcome:
| Outcome | Meaning | manifest.deployable |
|---|---|---|
deployable-verified | No bespoke infra, and the image built and served. | set to true, on evidence |
deployable-unverified | No bespoke infra, but nothing built it. | set to true, on static checks |
containerized-verified | Built and served, but needs backing infra. | left unset |
containerized-unverified | Needs backing infra, and unproven. | left unset |
verification-failed | Docker was usable and the recipe failed. | left unset, and a pre-existing flag is retracted |
verification-inconclusive | Verification was attempted and defeated by the environment — network, registry, or a runtime that could not exec the image here. It proves nothing, so nothing is retracted. Not the same as -unverified: that means nobody tried, this means you did and should retry. | set if static checks earned it |
blocked | The run stopped without a usable verdict. Four causes: a gate refused it up front (nothing written); a hard ERROR disqualified the recipe; the skill itself faulted; or verification was deferred pending uv lock — a pause, not a judgement, so re-invoke to finish. Check files_written (only a gate stop guarantees a clean tree) and read container-verify to tell a deferral from a real stop. | untouched — EXCEPT that a disqualified recipe has a stale flag retracted. Disqualified means a hard ERROR or no usable app object in agent.py, and the latter records no ERROR — so never infer from the absence of an ERROR that the tree was left alone. |
Never describe a containerized result as "deployable" to the user. Setting
that flag on a recipe that still needs hand-written terraform puts a false
claim in the manifest, which is worse than leaving it unset.
Equally, never describe an -unverified result as proven. It means the files
are right by inspection and nobody built the image — which is the normal
result on a machine without docker, not a defect.
Why -unverified still sets the flag. Absence of evidence is not evidence
of absence. Withholding it whenever docker is missing would judge the recipe
by the checker's laptop rather than by its own quality, and this skill's
primary user has no container runtime at all. Only a verification that
actually failed withholds the flag — a recipe proven broken is not
deployable, whatever the static checks said.
a2a.py does and does not proveNothing, on its own. These templates were designed assuming the project was
scaffolded by agents-cli, and a file named a2a.py does not make an agent
behave correctly over A2A. The skill copies and configures; it does not
certify. Say so in your summary — do not tell the owner their recipe "supports
A2A" because the file exists.
--apply. The skill writes six files and edits three.adk-locked-version,
adk-version-floor and legacy-app-utils return needs_input and stop the
run. Each means a human has to change code. Report the message verbatim and
stop; do not go hunting for a way around it.google-adk → google-adk[gcp,otel-gcp], same version bound), because
the generated code imports what those extras install and the recipe would
not start otherwise. Those are different risks: an extra only adds a
package's own optional dependencies, while a version rewrite can move the
recipe onto code it was never tested against.fast_api_app.py without explicit
confirmation. An existing one is usually bespoke — long-horizon-harness's
is ~400 lines of custom routing. --overwrite exists but is a deliberate
choice, not a default.uv run --no-project --with tomlkit --with 'ruamel.yaml' --with packaging \
python3 .agents/skills/make-python-recipe-deployable/scripts/make_deployable.py \
--recipe-dir <RECIPE_DIR>Prints a JSON report: outcome, agent_package, checks, todos, notes.
Nothing is written. Exit code 0 = fine, 1 = a gate needs human input,
2 = error.
Summarise it for the owner. Do not dump the raw JSON.
If any check is needs_input, stop. The three that gate:
adk-locked-version — uv.lock resolves google-adk to an older major
than the standard requires. The declared specifier may well permit the newer
version, which is exactly the trap — in both directions. Re-locking IN
PLACE keeps the old major (uv is sticky), so the recipe would ship the new
serving dependencies against an ADK that cannot support them; resolving
FRESH crosses the major silently,
and the agent code has only ever run against the old one. The owner must port
the agent first. This script rewrites metadata; it cannot migrate code.adk-version-floor — the specifier itself excludes the required version
(a <2.0.0 ceiling, an ==1.31.0 pin). Same conclusion.legacy-app-utils — the package carries the old ASP-era generation
(telemetry.py, typing.py, deploy.py, memory_config.py). Filenames do
not collide with the new set, but the two wire telemetry and services
differently and the existing fast_api_app.py imports the old ones.
Generating over the top orphans them or double-wires telemetry. A human
decides how to migrate.Also check already-deployable. If it is report_only, the recipe already
serves and you must confirm the owner wants to migrate onto the standard
layout before applying — see the advisory at the bottom of this file.
Ask only what applies. Keep it to one round.
assets/, sample_data/, a config file?
Those need COPY lines or the container fails at request time, not at
build time, which is why a human confirms rather than the skill guessing.
Pass them as --data-dirs assets,sample_data.report_only. Ask whether to keep it (default) or replace it
(--overwrite). Show what the existing file does first.google-adk>=2.2.0 against a
>=2.6.0 standard). Resolution usually lands on a satisfying version
anyway — a2a-sdk>=1.0 forces google-adk>=2.5 on its own — but confirm
the owner is happy rather than rewriting their pin.agents-cli-manifest.yaml, so it is a real decision. Default us-east1
(agents-cli's own). Pass --region us-central1 etc.containerized, confirm the
owner understands manifest.deployable stays unset and why.uv run --no-project --with tomlkit --with 'ruamel.yaml' --with packaging \
python3 .agents/skills/make-python-recipe-deployable/scripts/make_deployable.py \
--recipe-dir <RECIPE_DIR> --apply [--data-dirs a,b] [--overwrite] \
[--region us-central1]List files_written and the checks that moved to fixed.
When the script changes dependencies the lockfile goes stale, and the new files are unformatted. In order:
cd <RECIPE_DIR> && uv lock --python 3.11--python 3.11 because CI pins it — locking with a newer local interpreter
produces a lockfile CI rejects with a misleading "out of date" error.
Run the lock command the report's todos actually give you, and if they give you none, skip it. The report picks between three states rather than always asking for a re-lock:
| Report todo | State | What to run |
|---|---|---|
uv lock --upgrade-package google-adk --python 3.11 | Pinned below the ADK floor | That command — a plain uv lock here is a no-op |
uv lock --python 3.11 | This run changed dependencies, or uv says the lockfile is out of date | A plain re-lock |
| no lock todo | Nothing changed and uv lock --check passes | Nothing — re-locking would only churn uv.lock |
The third row is why an idempotent re-run is quiet. The script asks
uv lock --check before staying silent, so an earlier run that added
dependencies and never locked still produces the todo.
If adk-locked-version came back report_only, the recipe is pinned below
the ADK floor — uv keeps any locked version that still satisfies the declared
specifier. The report will hand you this instead:
cd <RECIPE_DIR> && uv lock --upgrade-package google-adk --python 3.11Then confirm the resolved pair. An ADK below 2.5 alongside a2a-sdk 1.x looks
fine in the lockfile and dies at import with cannot import name 'TextPart' from 'a2a.types' — invisible to every static check, and one of the reasons
Step 6.5 exists.
# from the REPO ROOT, so the root ruff config wins
uv run ruff format <RECIPE_DIR>/ && uv run ruff check --fix <RECIPE_DIR>/Then the repo validators:
uv run validate manifest <RECIPE_DIR>
uv run validate structure <RECIPE_DIR>
cd <RECIPE_DIR> && uv run pytest tests/ -qStatic checks cannot tell you the recipe actually serves. This can, it needs no
container runtime, and it is the closest thing to a correctness oracle the
skill has. Run it from inside the recipe after uv sync:
cd <RECIPE_DIR> && uv sync --python 3.11 && uv run --python 3.11 --with httpx python -c "
import warnings; warnings.filterwarnings('ignore')
from fastapi.testclient import TestClient
from <PKG>.fast_api_app import app
with TestClient(app) as c: # entering runs the lifespan
print('/list-apps ->', c.get('/list-apps').status_code, c.get('/list-apps').json())
card = [r.path for r in app.routes if 'well-known' in r.path]
print('agent card ->', c.get(card[0]).status_code if card else 'NO A2A ROUTES')
"Expected: /list-apps returns 200 listing the agent package, and the agent
card returns 200. Entering the TestClient context is what triggers the
lifespan — without it the A2A routes never attach and the check is worthless.
If the agent card 404s or no A2A routes exist, the A2A wiring did not take effect. Report that plainly; do not describe the recipe as A2A-capable.
Warnings about experimental InMemoryCredentialService are expected and
harmless.
Step 6 proves the app boots on this machine. This proves the image the recipe will actually be deployed as. It is the only step that turns "we generated a Dockerfile" into evidence, and it is what lets the word "deployable" mean anything.
Look at the docker check in the report. It is present in every run,
including the dry-run, and its details.docker_state is one of:
| State | Meaning | What you do |
|---|---|---|
absent | No docker on PATH. | Skip. Say nothing alarming — this is the common case, not a problem. |
unreachable | Binary present, daemon not answering. | Skip, same as above. Mention the daemon is down in case they want to start it. |
usable | Daemon responding. | Ask the owner (below). |
When and only when the state is usable, ask:
Docker is available. Shall I build the generated Dockerfile and check the container actually serves? It takes a few minutes, and it means
manifest.deployableis set on evidence rather than on inspection. If the container does not come up, I will not set the flag.
If they decline, carry on — the outcome ends -unverified and that is a
legitimate result. Do not decide for them, and do not skip the question
because verification seems slow.
On a "yes", re-invoke with both --apply and --verify-container.
--verify-container does not imply --apply — on its own it reports that
verification needs the files on disk, and builds nothing:
uv run --no-project --with tomlkit --with 'ruamel.yaml' --with packaging \
python3 .agents/skills/make-python-recipe-deployable/scripts/make_deployable.py \
--recipe-dir <RECIPE_DIR> --apply --verify-container [--data-dirs a,b]Run it after Step 5's uv lock, not before. The Dockerfile runs
uv sync --frozen, which cannot succeed until the lockfile matches. If the
lockfile is stale the script does not build — it defers manifest.deployable,
returns needs_input, and tells you to lock first. That is by design: a build
attempted against a stale lockfile fails with an error that looks exactly like
a broken template and is not.
What it does: builds for linux/amd64 (Cloud Run's platform), runs the
container with the recipe's own .env.example values plus the policy's
container_env, polls /list-apps until it answers, then probes the A2A
agent card. It removes the container and the image afterwards.
Reading the result:
container-build ERROR — the Dockerfile does not build. The check
carries a details.hint naming the likely structural cause. Report it and
stop; the recipe is not deployable.container-serves ERROR — the image builds but the app does not come
up. The log tail is in the message. manifest.deployable was not set.container-a2a REPORT_ONLY — it serves, but the agent card did not
return 200. The A2A wiring did not take effect. Say so plainly and do
not call the recipe A2A-capable.⚠️ Running a container is allowlisted, not automatic. Recipes not on
deployability.verification.run_allowlist are built only, because some
create real cloud resources at import — core/python/cross-session-memory
calls client.agent_engines.create() at module scope. A build-only result is
reported as unproven, never as a pass. Add a recipe to the allowlist only
after reading its package for import-time side effects.
Walk the report's todos with the owner — .env.example entries for any new
variables (the extract-python-environment-variables skill does this), and
terraform if the outcome was containerized.
If you created a .venv in the recipe to run Step 6 and it was not there
before, remove it.
| Not done | Why, and what does it instead |
|---|---|
| Deploying, or pushing an image anywhere | Out of scope by decision. Cloud Build builds and Artifact Registry stores the real image. Step 6.5 builds one only to verify its own output, then deletes it — docker is an instrument here, never a deployment mechanism. |
| Running a container that is not allowlisted | Some recipes create real cloud resources at import. Unlisted recipes are built only. |
| Migrating agent code across an ADK major | A code migration, not a metadata rewrite. Same stance as align-recipe-pyproject. |
Merging a legacy app_utils generation | Needs human judgement about telemetry and feedback wiring. |
| Writing terraform | Two deployable recipes in this repo share zero infrastructure resources; nothing is templatable. |
Removing [tool.ruff*], fixing requires-python | align-recipe-pyproject |
Completing .env.example | extract-python-environment-variables |
Running uv lock, ruff, or the boot check | You do, in Steps 5-6, so failures are attributable to the right step. |
agents-cli-manifest.yamlWritten when deployability.emit_agents_cli_manifest is true (it is).
This file is functional, not decorative. agents-cli uses it as the
project-root marker — find_project_root() walks up looking for it — and
agents-cli deploy reads create_params.deployment_target to choose how to
deploy. Without it, deploy reports "No agents-cli-manifest.yaml found".
The provenance problem — these recipes were never scaffolded by agents-cli — is handled by omitting the fields that would be fiction, not by skipping the file:
| Omitted | Why omission beats a value |
|---|---|
acli_version | No scaffold ran. check_cli_version returns early on an absent version; a fabricated one makes the CLI tell the owner to run agents-cli scaffold upgrade on a project that cannot be upgraded. |
generated_at | Never read by ProjectConfig.from_dict, and asserts an event that did not happen. |
base_template | Only used by upgrade/enhance. Already defaults to adk, so writing it changes nothing. |
Everything written is derived from the recipe or from what the skill just
generated. Verified against agents-cli 1.4.0's own parser: the project root
resolves, every field reads back correctly, and
require_agent_directory / require_deployment_target / require_a2a_project
all pass.
An existing agents-cli-manifest.yaml is never overwritten.
resources/templates/ holds the serving files, vendored from
agents-cli 1.4.0's scaffold/base_templates/python and
scaffold/deployment_targets/{cloud_run,agent_runtime}/python, rendered for
the cloud_run target with in-memory sessions, then formatted to this
repo's ruff config so generated files pass CI unmodified.
Two placeholders are substituted at copy time:
| Placeholder | Becomes |
|---|---|
__AGENT_PACKAGE__ | the recipe's agent package (app, horizon, ...) |
__PROJECT_NAME__ | [project].name from pyproject.toml |
Both are valid Python identifiers on purpose, so the templates parse and stay
lint-checked in place rather than only after substitution.
__AGENT_PACKAGE__ is registered in the root pyproject.toml's
known-first-party so isort orders template imports exactly as the rendered
output needs them.
Known divergences from agents-cli, all deliberate:
FROM python:X-slim is rewritten from the recipe's own
requires-python floor. The template hardcodes 3.12; recipes here target
3.11, 3.12 and 3.13.reasoning_engine_adapter.py's streaming route duck-types the object it is
about to iterate instead of assuming an async generator. streaming_methods
merges the operation registry's sync stream bucket with async_stream,
so async for over a method from the former raises
TypeError: 'async for' requires an object with __aiter__ method, got generator — at request time, only for whoever streams, and never during a
build. The sync route already drew exactly this distinction for the "" and
async buckets via iscoroutinefunction; the streaming route did not.
This is a fix to the vendored source, so re-rendering from a newer
agents-cli will silently revert it — re-check the streaming route after any
re-render.fast_api_app.py wires reasoning_engine_adapter.py in, which agents-cli
does only under agent_runtime. Published recipe images are deployed to
Agent Engine through container_spec, and Agent Engine forwards :query
and :streamQuery to /api/reasoning_engine and
/api/stream_reasoning_engine. Without the adapter the container starts
and 404s every call — the cloud_run render passes this skill's own
verification (which probes /list-apps) while being unusable on Agent
Engine. The adapter imports agentplatform, supplied by
google-cloud-aiplatform[agent-engines], hence that entry in
required_dependencies.Since these are vendored, they drift as agents-cli moves. Re-render from a newer agents-cli when the standard changes; do not hand-edit them to fix a single recipe.
Both taken through the full pipeline including Step 6.5, then reverted.
Deployable recipes live under core/ or contrib/; plugins/ is out of scope.
| Recipe | Outcome | What it proves |
|---|---|---|
contrib/python/financial-advisor | deployable-verified | Image builds, /list-apps → 200, agent card → 200, flag set on evidence. |
core/python/rag-agent-search | containerized-verified | Builds and serves, and the flag still correctly stays unset because it needs a datastore. The two axes compose. |
Three failures were found by building that no static check saw. All three are the reason this step exists:
financial-advisor crashed on import with no GOOGLE_CLOUD_PROJECT.
Its __init__.py does
os.environ.setdefault("GOOGLE_CLOUD_PROJECT", project_id) where
google.auth.default() yields None without credentials, and setdefault
only assigns when the key is absent. Not a recipe defect — Cloud Run always
supplies a project — so container_env now models the platform.rag-agent-search crashed on Gemini(model=None). It reads
MODEL_NAME, and .dockerignore correctly keeps .env out of the image.
Fixed by load_env_example, which seeds the container from the recipe's
own declared environment. Unconfigured is not the same as broken.rag-agent-search then failed with ImportError: cannot import name 'TextPart' from 'a2a.types' — a genuine incompatibility. It had resolved
to google-adk 2.3.0 against a2a-sdk 1.1.2, and adk ≤2.4.0 expects
a2a-sdk<0.4. See the warning below; this one is a live trap.⚠️
uv lockdoes not raise an already-locked version. uv is sticky: it preserves any locked version that still satisfies the declared specifier, so a recipe declaringgoogle-adk>=2.0.0stays on whatever it was pinned at.rag-agent-searchstayed on 2.3.0 through a plainuv lockand only moved to 2.7.1 underuv lock --upgrade-package google-adk. The coupling the policy leans on (a2a-sdk>=1.0forcing adk to 2.5+) travels with google-adk'sa2aextra, which the required dependency list does not use — so it never constrains resolution.The
adk-locked-versioncheck now states this correctly and emitsuv lock --upgrade-package google-adkas the remedy in itsdetailsand in the run's todos. Use the command the report gives you, not a plainuv lock, whenever that check isreport_only.
plugins/retail/product-search was taken through the pipeline before plugins/
was ruled out of scope for deployability. Kept as the record of what the Step 6
boot check looks like when it works:
uv lock resolved to google-adk 2.6.2 + a2a-sdk 1.1.2 — even though the
recipe's own bound is >=2.2.0, because a2a-sdk>=1.0 forces google-adk
to 2.5+ on its own. That coupling is the reason for the policy floor.app_utils modules import.fast_api_app:app builds — 71 routes, no credentials needed./list-apps → 200 ['scripts'], and
/a2a/scripts/.well-known/agent-card.json → 200.Measured by running the dry-run against every Python recipe under core/ and
contrib/ — not predicted. Deployable recipes live in those two trees;
plugins under plugins/ are out of scope.
Outcomes below are the dry-run's, so they all end -unverified: a dry run
builds nothing. Running with --apply --verify-container on a machine with
docker is what upgrades them (financial-advisor and rag-agent-search have
both been taken to deployable-verified and containerized-verified).
| Recipe | Dry-run outcome | Why |
|---|---|---|
contrib/python/financial-advisor | deployable-unverified | loose pin, but locked at 2.6.2 |
core/python/rag-agent-search, rag-vector-search | containerized-unverified | need a datastore / vector index |
core/python/long-horizon-harness, ambient-expense-agent | containerized-unverified + already-deployable flag | they already serve; see the advisory below |
contrib/python/market-research-agent, core/python/deep-search, core/python/safety-plugins | blocked | adk-locked-version — locked on ADK 1.x |
core/python/cross-session-memory, genmedia-for-commerce, oauth-user-consent-flow | blocked | adk-version-floor — the ceiling excludes the floor |
contrib/python/cross-border-data-router | blocked | legacy app_utils |
The already-deployable advisory. When a recipe already has a Dockerfile
and a <pkg>/fast_api_app.py, it serves by its own arrangement.
long-horizon-harness is the case: a bespoke ~400-line entrypoint wiring A2A
from its own horizon/a2a/ package. Neither file is replaced without
--overwrite, but app_utils/ modules generated alongside a bespoke
entrypoint are dead code unless someone wires them in. Confirm the owner
wants to migrate onto the standard layout before applying.
© google, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 8 other files (scripts) in .agents/skills/make-python-recipe-deployable of google/adk-recipes.
Open the folder on GitHubat commit c339821
Make Python Recipe Deployable next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Make Python Recipe Deployable this skillgoogle/adk-recipes | 10k | — | ~6.9k | Automated safety check: Notes | Apache-2.0 | |
| Devops Deploysickn33/agentic-awesome-skills | 47k | 2 repos | ~1.9k | Automated safety check: Pass | MIT | |
| Sca TrivyAgentSecOps/SecOpsAgentKit | 220 | 2 repos | ~3.7k | Automated safety check: Pass | Custom licence | |
| Security Analyzeraiskillstore/marketplace | 430 | — | ~1.2k | Automated safety check: Notes | None | |
| Senior DevOps Toolkitmaslennikov-ig/claude-code-orchestrator-kit | 260 | 6 repos | ~1.1k | Automated safety check: Notes | Custom licence | |
| Verifylkmeta/txtify | 135 | — | ~583 | Automated safety check: Pass | Apache-2.0 |
sickn33/agentic-awesome-skills
DevOps e deploy de aplicacoes — Docker, CI/CD com GitHub Actions, AWS Lambda, SAM, Terraform, infraestrutura como codigo e monitoramento.
AgentSecOps/SecOpsAgentKit
Software Composition Analysis (SCA) and container vulnerability scanning using Aqua Trivy for identifying CVE vulnerabilities in dependencies, container images, IaC misconfigurations, and license…
aiskillstore/marketplace
Comprehensive security vulnerability analysis for codebases and infrastructure.
maslennikov-ig/claude-code-orchestrator-kit
Comprehensive DevOps skill for CI/CD, infrastructure automation, containerization, and cloud platforms (AWS, GCP, Azure). Includes pipeline setup…
lkmeta/txtify
Verify a Txtify change end-to-end. An agent skill from lkmeta/txtify.
EliasOulkadi/shokunin
Optimize Docker images with multi-stage builds, distroless bases, BuildKit cache mounts, multi-arch builds, compose watch, security hardening (non-root, seccomp, capabilities drop), and…
google/adk-recipes
Builds a retail product search agent on Google Cloud, from catalog ingestion into BigQuery and Vector Search to ADK scaffolding, evaluation and Cloud Run deployment.
google/adk-recipes
Brings a Python recipe's pyproject.toml in line with the repo's CI rules, either as a read-only dry run or by rewriting the file while keeping comments.
google/adk-recipes
Generates a minimal tests/test_runnability.py for a Python agent recipe that imports the agent module and checks root_agent, adding only the mocks and env vars it needs.
google/adk-recipes
Sets up a virtual try-on agent on Google Cloud that generates image and catwalk-video try-ons with Gemini, from first setup through local testing.
google/adk-recipes
Creates a new Python recipe for the ADK recipes repository by running a scaffold script that copies template files, after confirming the output directory and recipe name.
google/adk-recipes
Reviews a GitHub pull request and drafts a small set of inline comments in a human reviewing voice, each checkable from the line it points at, then posts them after approval.
Categories
Makes an existing Python recipe deployable: generates the serving files a container needs (Dockerfile, .dockerignore, fastapiapp.py, apputils/a2a.py, apputils/services.py…. Make Python Recipe Deployable is an agent skill from google/adk-recipes, published by the product's own GitHub organization.deployable).
Make Python Recipe Deployable fits situations like: the user wants to make this recipe deployable; add a Dockerfile to a recipe; add the serving files; containerize a recipe.
Run `npx skills add google/adk-recipes --skill make-python-recipe-deployable -a claude-code`. Or copy the skill folder (.agents/skills/make-python-recipe-deployable in google/adk-recipes) into .claude/skills/make-python-recipe-deployable in your project. Claude Code loads it when a task matches its description.
Run `npx skills add google/adk-recipes --skill make-python-recipe-deployable -a codex`. Or copy the skill folder (.agents/skills/make-python-recipe-deployable in google/adk-recipes) into .agents/skills/make-python-recipe-deployable in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add google/adk-recipes --skill make-python-recipe-deployable -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/make-python-recipe-deployable, .gemini/skills/make-python-recipe-deployable, .github/skills/make-python-recipe-deployable and .opencode/skills/make-python-recipe-deployable in your project.
Going by SKILL.md and its folder, Make Python Recipe Deployable needs Python for the scripts in its folder and the command-line tools its instructions call (uv and python3). Our summary lists: Python 3; Docker.
SKILL.md contains no URLs. Its commands use uv, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Make Python Recipe Deployable is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 6.9k tokens (SKILL.md is roughly 28k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Make Python Recipe Deployable: Devops Deploy (sickn33/agentic-awesome-skills, 47k stars), Sca Trivy (AgentSecOps/SecOpsAgentKit, 220 stars), Security Analyzer (aiskillstore/marketplace, 430 stars) and Senior DevOps Toolkit (maslennikov-ig/claude-code-orchestrator-kit, 260 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
google (a GitHub organization, an official publisher) maintains it in google/adk-recipes, which has 10,421 GitHub stars. The repository holds 14 skills in this directory. The repository was last updated on October 8, 2026.
Source: google/adk-recipes on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.