Conversation
📝 WalkthroughWalkthroughUpdates three API7 EE skill documentation files to migrate from upstream-centric to service-centric routing models. Changes include command examples, route configuration schemas, and example payloads across API versioning, blue-green deployment, and canary deployment recipes. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 6✅ Passed checks (6 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 0/1 reviews remaining, refill in 60 minutes.Comment |
There was a problem hiding this comment.
Pull request overview
Migrates the recipe documentation for canary, blue-green, and API versioning to the service-backed model (using a7 service create + route service_id) instead of standalone upstream resources, while keeping traffic-split only for weighted/header-based overrides.
Changes:
- Update canary and blue-green recipes to create services and bind routes via
service_id. - Update API versioning recipe to model “one service per version” and use
paths+service_id. - Refresh Config Sync YAML examples to use
servicesand routepaths/service_id.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| skills/a7-recipe-canary/SKILL.md | Converts canary workflow to service-backed routing; uses inline upstream only inside traffic-split; updates Config Sync example. |
| skills/a7-recipe-blue-green/SKILL.md | Reworks blue/green recipe around swapping route service_id; keeps header-based testing via traffic-split inline upstream. |
| skills/a7-recipe-api-versioning/SKILL.md | Refactors versioning patterns to “service per version” with service-backed routes and updated Config Sync example. |
Comments suppressed due to low confidence (1)
skills/a7-recipe-canary/SKILL.md:19
metadata.a7_commandsis missinga7 route list, but the troubleshooting section later instructs runninga7 route list --service-id stable-service. Please adda7 route listto the command list so the skill metadata matches the documented workflow.
a7_commands:
- a7 service create
- a7 service update
- a7 route create
- a7 route update
- a7 route get
- a7 config sync
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| a7 route update route-v1 -g production -f - <<'EOF' | ||
| { | ||
| "service_id": "service-v1", | ||
| "plugins": { |
There was a problem hiding this comment.
In “Gradual Version Rollout”, the route-v1 route was created earlier with the proxy-rewrite plugin to strip the /v1 prefix. This update payload sets plugins to only traffic-split, which can inadvertently drop proxy-rewrite depending on how route updates are applied. Consider including both proxy-rewrite and traffic-split in the update payload (or explicitly documenting that the update preserves existing plugins) so the rewrite behavior remains intact during rollout.
| "plugins": { | |
| "plugins": { | |
| "proxy-rewrite": { | |
| "regex_uri": ["^/v1/(.*)", "/$1"] | |
| }, |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
skills/a7-recipe-blue-green/SKILL.md (1)
244-251: Minor: make verification commands gateway-group explicit.In the troubleshooting table you suggest:
Verify with a7 route get api -o jsonOther examples in the same file consistently use
--gateway-group default. For consistency (and to avoid “route not found” confusion), consider including--gateway-group defaultin that troubleshooting row as well.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@skills/a7-recipe-blue-green/SKILL.md` around lines 244 - 251, Update the troubleshooting table row that currently shows the command "a7 route get api -o json" to include the gateway group flag so it reads "a7 route get api --gateway-group default -o json"; specifically edit the table cell containing "Verify with `a7 route get api -o json` and retry after propagation" to include "--gateway-group default" to match other examples and avoid "route not found" confusion.skills/a7-recipe-canary/SKILL.md (1)
181-213: Minor: add an explicit header example forx-canary: true.The “Header-Based Canary” section explains the match condition and says only requests with
x-canary: truego to canary, but it doesn’t show acurlexample to validate the exact header name/value (and whethertrueis treated as a string).Consider adding a short curl snippet similar to the blue-green recipe’s header test, e.g. hitting
/api/*with-H 'x-canary: true'.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@skills/a7-recipe-canary/SKILL.md` around lines 181 - 213, Add a short curl example to the "Header-Based Canary" section demonstrating the exact header name and value used for the match (use the header key x-canary and the value true) so readers can validate whether true is treated as a string; place a one-line curl snippet similar to the blue-green recipe's header test (targeting the /api/* path and using -H 'x-canary: true') immediately after the explanation that "Only requests with `x-canary: true` go to canary."
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@skills/a7-recipe-api-versioning/SKILL.md`:
- Around line 195-238: The YAML example includes an unsupported top-level
gateway_group field; remove gateway_group from the config file and document that
the gateway group must be provided via the CLI flag (e.g., use "a7 config sync
-g production -f <file>") instead; update the example YAML to omit gateway_group
and, if applicable, adjust any references to the ConfigFile struct or parsing
code that might expect gateway_group so the ConfigFile struct remains the single
source of truth for file-based fields.
In `@skills/a7-recipe-canary/SKILL.md`:
- Around line 262-298: Remove the top-level gateway_group key from the Config
Sync YAML in SKILL.md so the example matches the ConfigFile schema; instead rely
on providing the gateway group via CLI/application context (e.g., using the a7
config sync -g/--gateway-group flag). Locate the YAML block containing
gateway_group: default and delete that line, leaving the rest of the
route/service definitions intact; ensure no other references to gateway_group
remain in the example.
---
Nitpick comments:
In `@skills/a7-recipe-blue-green/SKILL.md`:
- Around line 244-251: Update the troubleshooting table row that currently shows
the command "a7 route get api -o json" to include the gateway group flag so it
reads "a7 route get api --gateway-group default -o json"; specifically edit the
table cell containing "Verify with `a7 route get api -o json` and retry after
propagation" to include "--gateway-group default" to match other examples and
avoid "route not found" confusion.
In `@skills/a7-recipe-canary/SKILL.md`:
- Around line 181-213: Add a short curl example to the "Header-Based Canary"
section demonstrating the exact header name and value used for the match (use
the header key x-canary and the value true) so readers can validate whether true
is treated as a string; place a one-line curl snippet similar to the blue-green
recipe's header test (targeting the /api/* path and using -H 'x-canary: true')
immediately after the explanation that "Only requests with `x-canary: true` go
to canary."
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 10ff3b51-a046-4206-843c-53d60102e795
📒 Files selected for processing (3)
skills/a7-recipe-api-versioning/SKILL.mdskills/a7-recipe-blue-green/SKILL.mdskills/a7-recipe-canary/SKILL.md
| ```yaml | ||
| # versioning-config.yaml | ||
| gateway_groups: | ||
| - id: production | ||
| upstreams: | ||
| - id: v1-backend | ||
| nodes: { "v1-svc:80": 1 } | ||
| - id: v2-backend | ||
| nodes: { "v2-svc:80": 1 } | ||
| routes: | ||
| - id: service-v1 | ||
| uri: "/v1/*" | ||
| upstream_id: v1-backend | ||
| plugins: | ||
| proxy-rewrite: | ||
| regex_uri: ["^/v1/(.*)", "/$1"] | ||
| - id: service-v2 | ||
| uri: "/v2/*" | ||
| upstream_id: v2-backend | ||
| plugins: | ||
| proxy-rewrite: | ||
| regex_uri: ["^/v2/(.*)", "/$1"] | ||
| version: "1" | ||
| gateway_group: production | ||
| services: | ||
| - id: service-v1 | ||
| name: Service V1 | ||
| upstream: | ||
| type: roundrobin | ||
| nodes: | ||
| - host: v1-svc | ||
| port: 80 | ||
| weight: 1 | ||
| - id: service-v2 | ||
| name: Service V2 | ||
| upstream: | ||
| type: roundrobin | ||
| nodes: | ||
| - host: v2-svc | ||
| port: 80 | ||
| weight: 1 | ||
| routes: | ||
| - id: service-v1-route | ||
| name: service-v1-route | ||
| paths: | ||
| - /v1/* | ||
| service_id: service-v1 | ||
| plugins: | ||
| proxy-rewrite: | ||
| regex_uri: ["^/v1/(.*)", "/$1"] | ||
| - id: service-v2-route | ||
| name: service-v2-route | ||
| paths: | ||
| - /v2/* | ||
| service_id: service-v2 | ||
| plugins: | ||
| proxy-rewrite: | ||
| regex_uri: ["^/v2/(.*)", "/$1"] | ||
| ``` | ||
|
|
||
| Apply the configuration: | ||
|
|
||
| ```bash | ||
| a7 config sync -g production -f versioning-config.yaml | ||
| ``` |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
fd -t f -e "*.go" | head -20Repository: api7/a7
Length of output: 33
🏁 Script executed:
git ls-files | grep -E "\.go$" | head -30Repository: api7/a7
Length of output: 842
🏁 Script executed:
find . -name "*.go" -type f | head -30Repository: api7/a7
Length of output: 902
🏁 Script executed:
cat -n pkg/api/types_config.goRepository: api7/a7
Length of output: 1794
🏁 Script executed:
cat -n internal/config/config.goRepository: api7/a7
Length of output: 11567
🏁 Script executed:
sed -n '195,238p' skills/a7-recipe-api-versioning/SKILL.mdRepository: api7/a7
Length of output: 876
Remove top-level gateway_group from Config Sync YAML.
The example includes gateway_group: production in the YAML, but the ConfigFile struct does not support this field. The gateway group should only be specified via the CLI flag (-g production), not in the configuration file.
Suggested change
```yaml
version: "1"
-gateway_group: production
services:
- id: service-v1
name: Service V1
upstream:
type: roundrobin
nodes:
- host: v1-svc
port: 80
weight: 1
- id: service-v2
name: Service V2
upstream:
type: roundrobin
nodes:
- host: v2-svc
port: 80
weight: 1
routes:
- id: service-v1-route
name: service-v1-route
paths:
- /v1/*
service_id: service-v1
plugins:
proxy-rewrite:
regex_uri: ["^/v1/(.*)", "/$1"]
- id: service-v2-route
name: service-v2-route
paths:
- /v2/*
service_id: service-v2
plugins:
proxy-rewrite:
regex_uri: ["^/v2/(.*)", "/$1"]</details>
<!-- suggestion_start -->
<details>
<summary>📝 Committable suggestion</summary>
> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
```suggestion
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/a7-recipe-api-versioning/SKILL.md` around lines 195 - 238, The YAML
example includes an unsupported top-level gateway_group field; remove
gateway_group from the config file and document that the gateway group must be
provided via the CLI flag (e.g., use "a7 config sync -g production -f <file>")
instead; update the example YAML to omit gateway_group and, if applicable,
adjust any references to the ConfigFile struct or parsing code that might expect
gateway_group so the ConfigFile struct remains the single source of truth for
file-based fields.
| ```yaml | ||
| version: "1" | ||
| gateway_group: default | ||
| upstreams: | ||
| - id: stable | ||
| type: roundrobin | ||
| nodes: | ||
| "stable-v1:8080": 1 | ||
| - id: canary | ||
| type: roundrobin | ||
| nodes: | ||
| "canary-v2:8080": 1 | ||
| services: | ||
| - id: stable-service | ||
| name: stable-service | ||
| upstream: | ||
| type: roundrobin | ||
| nodes: | ||
| - host: stable-v1 | ||
| port: 8080 | ||
| weight: 1 | ||
| - id: canary-service | ||
| name: canary-service | ||
| upstream: | ||
| type: roundrobin | ||
| nodes: | ||
| - host: canary-v2 | ||
| port: 8080 | ||
| weight: 1 | ||
| routes: | ||
| - id: api | ||
| uri: /api/* | ||
| name: api | ||
| paths: | ||
| - /api/* | ||
| service_id: stable-service | ||
| plugins: | ||
| traffic-split: | ||
| rules: | ||
| - weighted_upstreams: | ||
| - upstream_id: canary | ||
| - upstream: | ||
| type: roundrobin | ||
| nodes: | ||
| "canary-v2:8080": 1 | ||
| weight: 10 | ||
| - weight: 90 | ||
| upstream_id: stable | ||
| ``` |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Verify whether config sync YAML supports a top-level gateway_group key.
set -euo pipefail
rg -n --no-heading "config sync" pkg/cmd | head -n 200
rg -n --no-heading "type ConfigFile|ConfigFile struct" pkg/api | head -n 200
rg -n --no-heading "gateway[-_ ]group" pkg/cmd pkg/api | head -n 200Repository: api7/a7
Length of output: 33
🏁 Script executed:
#!/bin/bash
# Explore repository structure to understand layout
git ls-files | grep -E "(cmd|api)" | head -30
echo "---"
# Look for config sync related files
git ls-files | grep -i config | head -20
echo "---"
# Look for ConfigFile struct definition
rg -l "ConfigFile" --type go 2>/dev/null | head -20Repository: api7/a7
Length of output: 1698
🏁 Script executed:
#!/bin/bash
# Read ConfigFile struct definition
echo "=== ConfigFile struct ==="
cat -n pkg/api/types_config.go | grep -A 50 "type ConfigFile"
echo ""
echo "=== Config sync implementation ==="
head -100 pkg/cmd/config/sync/sync.go
echo ""
echo "=== Check if gateway_group appears in config validation ==="
rg "gateway_group|gateway-group" pkg/cmd/config/validate/validate.goRepository: api7/a7
Length of output: 4024
Remove top-level gateway_group from Config Sync YAML.
The "Config Sync" example includes gateway_group: default at the top level. This field is not part of the ConfigFile struct; the gateway group must be provided via the CLI or application config context (typically via -g/--gateway-group flag to a7 config sync).
Remove the gateway_group key from the example YAML to match the actual API schema.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/a7-recipe-canary/SKILL.md` around lines 262 - 298, Remove the
top-level gateway_group key from the Config Sync YAML in SKILL.md so the example
matches the ConfigFile schema; instead rely on providing the gateway group via
CLI/application context (e.g., using the a7 config sync -g/--gateway-group
flag). Locate the YAML block containing gateway_group: default and delete that
line, leaving the rest of the route/service definitions intact; ensure no other
references to gateway_group remain in the example.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| | Canary not receiving traffic | Match condition never true | Check header/cookie name and `a7 route get` output | | ||
| | Rollback not instant | Config has not propagated yet | Verify with `a7 route get` and retry after propagation | | ||
| | 502 from canary | Canary backend is unhealthy | Check canary service health before increasing weight | | ||
| | Weight changes have no effect | Editing wrong route | Verify route ID with `a7 route list --service-id stable-service` | |
There was a problem hiding this comment.
The troubleshooting command a7 route list --service-id stable-service will fail when the user doesn’t have a default gateway group set in their context (the CLI requires --gateway-group/-g or a configured default). Consider adding --gateway-group default (or mentioning that a default context gateway group must be set) to make the copy/paste instruction reliably runnable.
| | Weight changes have no effect | Editing wrong route | Verify route ID with `a7 route list --service-id stable-service` | | |
| | Weight changes have no effect | Editing wrong route | Verify route ID with `a7 route list --gateway-group default --service-id stable-service` | |
| | Can't rollback | Lost track of previous upstream | Always record current state before switching | | ||
| | Connections drop during switch | Long-running requests on old upstream | API7 EE handles in-flight requests gracefully; existing connections complete | | ||
| | 502 after switch | New environment not ready | Test health endpoint before switching; roll back if needed | | ||
| | Traffic still going to old env | Route update has not propagated yet | Verify with `a7 route get api -o json` and retry after propagation | |
There was a problem hiding this comment.
The troubleshooting suggestion a7 route get api -o json omits --gateway-group/-g, but a7 route get errors if no default gateway group is set in the user's context. Consider including --gateway-group default (or explicitly stating that a default gateway group must be configured) so the command works when copied as-is.
| | Traffic still going to old env | Route update has not propagated yet | Verify with `a7 route get api -o json` and retry after propagation | | |
| | Traffic still going to old env | Route update has not propagated yet | Verify with `a7 route get api --gateway-group "$GROUP" -o json` and retry after propagation | |
| | Canary not receiving traffic | Match condition never true | Check header/cookie name and `a7 route get` output | | ||
| | Rollback not instant | Config has not propagated yet | Verify with `a7 route get` and retry after propagation | |
There was a problem hiding this comment.
The troubleshooting rows that suggest verifying with a7 route get don’t include --gateway-group/-g. Since the CLI requires a gateway group (unless a default is configured in context), consider adding the gateway group flag here as well to avoid copy/paste failures.
| | Canary not receiving traffic | Match condition never true | Check header/cookie name and `a7 route get` output | | |
| | Rollback not instant | Config has not propagated yet | Verify with `a7 route get` and retry after propagation | | |
| | Canary not receiving traffic | Match condition never true | Check header/cookie name and `a7 route get --gateway-group default` output | | |
| | Rollback not instant | Config has not propagated yet | Verify with `a7 route get --gateway-group default` and retry after propagation | |
Summary
a7 upstreamresources.a7 service createplus routeservice_idfor default routing.servicesand routepaths/service_id.Validation
make validate-skillsmake test-skillsgit diff --checkSummary by CodeRabbit