Skip to content

Commit aa62e8c

Browse files
committed
feat: release v2.3.0 with full OpenAPI coverage and generated registry
Refresh 14 Amazon CDN specs, regenerate 78 client modules (699 deduplicated operations), add client.generated registry and audit_coverage guard, align Marketing Stream with official OpenAPI, and enable unified GA codegen.
1 parent d54a701 commit aa62e8c

97 files changed

Lines changed: 19161 additions & 8559 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.githooks/prepare-commit-msg

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/sh
2+
# Strip Cursor agent attribution from commit messages (local hook).
3+
# Enable: git config core.hooksPath .githooks
4+
MSG_FILE=$1
5+
if [ -f "$MSG_FILE" ]; then
6+
sed -i '' '/[Cc]o-authored-by:.*[Cc]ursor/d' "$MSG_FILE" 2>/dev/null || sed -i '/[Cc]o-authored-by:.*[Cc]ursor/d' "$MSG_FILE"
7+
sed -i '' '/Made-with:.*[Cc]ursor/d' "$MSG_FILE" 2>/dev/null || sed -i '/Made-with:.*[Cc]ursor/d' "$MSG_FILE"
8+
fi
Lines changed: 121 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -1,121 +1,121 @@
1-
name: Check Spec Updates
2-
3-
on:
4-
schedule:
5-
# Run daily at 08:00 UTC (every day)
6-
- cron: "0 8 * * *"
7-
workflow_dispatch: # Allow manual trigger
8-
9-
permissions:
10-
issues: write
11-
contents: read
12-
13-
jobs:
14-
check-updates:
15-
runs-on: ubuntu-latest
16-
17-
steps:
18-
- uses: actions/checkout@v4
19-
20-
- name: Set up Python
21-
uses: actions/setup-python@v5
22-
with:
23-
python-version: "3.12"
24-
25-
- name: Install dependencies
26-
run: pip install pyyaml
27-
28-
- name: Check for spec updates
29-
id: check
30-
run: |
31-
python scripts/check_spec_updates.py --full --json > /tmp/spec_report.json 2>&1 || true
32-
cat /tmp/spec_report.json
33-
echo "report<<EOF" >> $GITHUB_OUTPUT
34-
cat /tmp/spec_report.json >> $GITHUB_OUTPUT
35-
echo "EOF" >> $GITHUB_OUTPUT
36-
37-
# Set has_updates flag
38-
HAS_UPDATES=$(python -c "import json; r=json.load(open('/tmp/spec_report.json')); print('true' if r.get('has_updates') else 'false')")
39-
echo "has_updates=$HAS_UPDATES" >> $GITHUB_OUTPUT
40-
41-
- name: Create issue if updates found
42-
if: steps.check.outputs.has_updates == 'true'
43-
uses: actions/github-script@v7
44-
with:
45-
script: |
46-
const report = JSON.parse(`${{ steps.check.outputs.report }}`);
47-
const changes = report.changes || [];
48-
49-
if (changes.length === 0) return;
50-
51-
// Check if there's already an open issue for spec updates
52-
const { data: existingIssues } = await github.rest.issues.listForRepo({
53-
owner: context.repo.owner,
54-
repo: context.repo.repo,
55-
state: 'open',
56-
labels: 'spec-update',
57-
per_page: 1,
58-
});
59-
60-
if (existingIssues.length > 0) {
61-
// Update existing issue with new findings
62-
const issue = existingIssues[0];
63-
const newBody = issue.body + `\n\n---\n### Update ${new Date().toISOString().split('T')[0]}\n\n` +
64-
changes.map(c => `- **[${c.status}]** \`${c.file}\`: ${c.detail}`).join('\n');
65-
66-
await github.rest.issues.update({
67-
owner: context.repo.owner,
68-
repo: context.repo.repo,
69-
issue_number: issue.number,
70-
body: newBody,
71-
});
72-
73-
console.log(`Updated existing issue #${issue.number}`);
74-
return;
75-
}
76-
77-
// Create new issue
78-
const changeList = changes.map(c =>
79-
`| \`${c.file}\` | ${c.status} | ${c.detail} |`
80-
).join('\n');
81-
82-
const body = `## Amazon Ads API Spec Updates Detected
83-
84-
The daily spec check found **${changes.length}** change(s) in the upstream OpenAPI specifications.
85-
86-
| File | Status | Detail |
87-
|------|--------|--------|
88-
${changeList}
89-
90-
### Action Required
91-
92-
1. Download updated specs:
93-
\`\`\`bash
94-
python download_specs.py
95-
\`\`\`
96-
97-
2. Regenerate models and clients:
98-
\`\`\`bash
99-
python -m codegen.generate -v
100-
\`\`\`
101-
102-
3. Run tests:
103-
\`\`\`bash
104-
pytest tests/unit/ -v
105-
\`\`\`
106-
107-
4. Review changes and commit.
108-
109-
---
110-
*Auto-generated by [check-spec-updates](.github/workflows/check-spec-updates.yml)*
111-
`.replace(/^ /gm, '');
112-
113-
await github.rest.issues.create({
114-
owner: context.repo.owner,
115-
repo: context.repo.repo,
116-
title: `[Auto] Amazon Ads API spec updates detected (${changes.length} changes)`,
117-
body: body,
118-
labels: ['spec-update', 'automated'],
119-
});
120-
121-
console.log('Created new spec update issue');
1+
name: Check Spec Updates
2+
3+
on:
4+
schedule:
5+
# Run daily at 08:00 UTC (every day)
6+
- cron: "0 8 * * *"
7+
workflow_dispatch: # Allow manual trigger
8+
9+
permissions:
10+
issues: write
11+
contents: read
12+
13+
jobs:
14+
check-updates:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Set up Python
21+
uses: actions/setup-python@v5
22+
with:
23+
python-version: "3.12"
24+
25+
- name: Install dependencies
26+
run: pip install pyyaml
27+
28+
- name: Check for spec updates
29+
id: check
30+
run: |
31+
python scripts/check_spec_updates.py --full --json > /tmp/spec_report.json 2>&1 || true
32+
cat /tmp/spec_report.json
33+
echo "report<<EOF" >> $GITHUB_OUTPUT
34+
cat /tmp/spec_report.json >> $GITHUB_OUTPUT
35+
echo "EOF" >> $GITHUB_OUTPUT
36+
37+
# Set has_updates flag
38+
HAS_UPDATES=$(python -c "import json; r=json.load(open('/tmp/spec_report.json')); print('true' if r.get('has_updates') else 'false')")
39+
echo "has_updates=$HAS_UPDATES" >> $GITHUB_OUTPUT
40+
41+
- name: Create issue if updates found
42+
if: steps.check.outputs.has_updates == 'true'
43+
uses: actions/github-script@v7
44+
with:
45+
script: |
46+
const report = JSON.parse(`${{ steps.check.outputs.report }}`);
47+
const changes = report.changes || [];
48+
49+
if (changes.length === 0) return;
50+
51+
// Check if there's already an open issue for spec updates
52+
const { data: existingIssues } = await github.rest.issues.listForRepo({
53+
owner: context.repo.owner,
54+
repo: context.repo.repo,
55+
state: 'open',
56+
labels: 'spec-update',
57+
per_page: 1,
58+
});
59+
60+
if (existingIssues.length > 0) {
61+
// Update existing issue with new findings
62+
const issue = existingIssues[0];
63+
const newBody = issue.body + `\n\n---\n### Update ${new Date().toISOString().split('T')[0]}\n\n` +
64+
changes.map(c => `- **[${c.status}]** \`${c.file}\`: ${c.detail}`).join('\n');
65+
66+
await github.rest.issues.update({
67+
owner: context.repo.owner,
68+
repo: context.repo.repo,
69+
issue_number: issue.number,
70+
body: newBody,
71+
});
72+
73+
console.log(`Updated existing issue #${issue.number}`);
74+
return;
75+
}
76+
77+
// Create new issue
78+
const changeList = changes.map(c =>
79+
`| \`${c.file}\` | ${c.status} | ${c.detail} |`
80+
).join('\n');
81+
82+
const body = `## Amazon Ads API Spec Updates Detected
83+
84+
The daily spec check found **${changes.length}** change(s) in the upstream OpenAPI specifications.
85+
86+
| File | Status | Detail |
87+
|------|--------|--------|
88+
${changeList}
89+
90+
### Action Required
91+
92+
1. Download updated specs:
93+
\`\`\`bash
94+
python download_specs.py
95+
\`\`\`
96+
97+
2. Regenerate models and clients:
98+
\`\`\`bash
99+
python -m codegen.generate -v
100+
\`\`\`
101+
102+
3. Run tests:
103+
\`\`\`bash
104+
pytest tests/unit/ -v
105+
\`\`\`
106+
107+
4. Review changes and commit.
108+
109+
---
110+
*Auto-generated by [check-spec-updates](.github/workflows/check-spec-updates.yml)*
111+
`.replace(/^ /gm, '');
112+
113+
await github.rest.issues.create({
114+
owner: context.repo.owner,
115+
repo: context.repo.repo,
116+
title: `[Auto] Amazon Ads API spec updates detected (${changes.length} changes)`,
117+
body: body,
118+
labels: ['spec-update', 'automated'],
119+
});
120+
121+
console.log('Created new spec update issue');

.github/workflows/ci.yml

Lines changed: 64 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,64 @@
1-
name: CI
2-
3-
on:
4-
push:
5-
branches: [main]
6-
pull_request:
7-
branches: [main]
8-
9-
jobs:
10-
test:
11-
runs-on: ubuntu-latest
12-
13-
steps:
14-
- uses: actions/checkout@v4
15-
16-
- name: Set up Python
17-
uses: actions/setup-python@v5
18-
with:
19-
python-version: "3.13"
20-
21-
- name: Install dependencies
22-
run: |
23-
python -m pip install --upgrade pip
24-
pip install -e ".[dev]"
25-
pip install pyyaml
26-
27-
- name: Lint with ruff
28-
run: |
29-
pip install ruff
30-
ruff check amazon_ads_api/ codegen/ --select E,F,W --ignore E501,F403,F405,W291,W293,E402,F821
31-
32-
- name: Run unit tests
33-
run: pytest tests/unit/ -v --tb=short
34-
35-
- name: Validate codegen (dry run)
36-
run: python -m codegen.generate --dry-run
37-
38-
- name: Verify generated code matches specs
39-
run: |
40-
python -m codegen.generate
41-
git diff --exit-code amazon_ads_api/generated/ || {
42-
echo "Generated code is out of sync with specs!"
43-
echo "Run 'python -m codegen.generate' and commit the results."
44-
exit 1
45-
}
46-
47-
- name: Validate all generated files syntax
48-
run: |
49-
python -c "
50-
import ast, os, sys
51-
errors = 0
52-
for root, dirs, files in os.walk('amazon_ads_api/generated'):
53-
for f in files:
54-
if f.endswith('.py'):
55-
path = os.path.join(root, f)
56-
try:
57-
ast.parse(open(path).read())
58-
except SyntaxError as e:
59-
print(f'SYNTAX ERROR: {path}: {e}')
60-
errors += 1
61-
if errors:
62-
sys.exit(1)
63-
print(f'All generated files valid')
64-
"
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v5
18+
with:
19+
python-version: "3.13"
20+
21+
- name: Install dependencies
22+
run: |
23+
python -m pip install --upgrade pip
24+
pip install -e ".[dev]"
25+
pip install pyyaml
26+
27+
- name: Lint with ruff
28+
run: |
29+
pip install ruff
30+
ruff check amazon_ads_api/ codegen/ --select E,F,W --ignore E501,F403,F405,W291,W293,E402,F821
31+
32+
- name: Run unit tests
33+
run: pytest tests/unit/ -v --tb=short
34+
35+
- name: Validate codegen (dry run)
36+
run: python -m codegen.generate --dry-run
37+
38+
- name: Verify generated code matches specs
39+
run: |
40+
python -m codegen.generate
41+
git diff --exit-code amazon_ads_api/generated/ || {
42+
echo "Generated code is out of sync with specs!"
43+
echo "Run 'python -m codegen.generate' and commit the results."
44+
exit 1
45+
}
46+
47+
- name: Validate all generated files syntax
48+
run: |
49+
python -c "
50+
import ast, os, sys
51+
errors = 0
52+
for root, dirs, files in os.walk('amazon_ads_api/generated'):
53+
for f in files:
54+
if f.endswith('.py'):
55+
path = os.path.join(root, f)
56+
try:
57+
ast.parse(open(path).read())
58+
except SyntaxError as e:
59+
print(f'SYNTAX ERROR: {path}: {e}')
60+
errors += 1
61+
if errors:
62+
sys.exit(1)
63+
print(f'All generated files valid')
64+
"

0 commit comments

Comments
 (0)