-
-
Notifications
You must be signed in to change notification settings - Fork 0
160 lines (147 loc) · 7 KB
/
Copy pathsmithy-sync.yml
File metadata and controls
160 lines (147 loc) · 7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
name: Smithy Model Sync
on:
schedule:
- cron: "0 0 * * 1" # Every Monday at midnight UTC
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Set up Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v6
with:
go-version: "1.26"
- name: Download latest Smithy models
# --refresh re-downloads the committed models; without it every model
# already in the tree is skipped and this job can never find a change.
run: bash scripts/download-smithy-models.sh --refresh
- name: Run code generation
run: |
go run ./cmd/codegen \
-models ./smithy-models \
-output ./internal/generated \
-templates ./internal/codegen/templates \
-scaffold-output ./internal/services
- name: Regenerate imports
run: bash scripts/generate-imports.sh
- name: Check for changes
id: changes
# --porcelain rather than `git diff --quiet` so a newly generated
# package (an untracked directory) counts as a change instead of being
# silently dropped on the runner.
run: |
if [ -z "$(git status --porcelain)" ]; then
echo "changed=false" >> $GITHUB_OUTPUT
else
echo "changed=true" >> $GITHUB_OUTPUT
fi
# continue-on-error, not a gate: this suite includes the published-figure
# gate in cmd/devcloud/coverage_test.go, which an upstream model that gains
# a single operation is *designed* to fail. Ending the job here would skip
# Create Pull Request and discard the refreshed models with the runner —
# so the only sync worth reviewing would be the only one nobody ever sees.
# The failure is not swallowed; it is re-raised below, after the PR exists.
- name: Run tests
id: tests
if: steps.changes.outputs.changed == 'true'
continue-on-error: true
run: CGO_ENABLED=0 go test ./... -v
# The gate above fails on purpose when upstream moves an operation, and
# until now the fix was a person transcribing nine numbers out of four
# failure messages into three files. This does that arithmetic and leaves
# it in the PR, so the review is "should ec2 have gained 46 operations?"
# rather than "is 19,247 the right total?".
#
# It does not relax the gate: this runs before the PR's own ci, which
# still asserts docs/coverage.md against the binary in both directions. A
# change that needs a sentence rather than a number — a service that has
# newly stopped serving anything, which the page must name — makes this
# step exit non-zero, and the body says so.
#
# It must stay *after* Run tests. cmd/devcloud/sync_test.go finds the test
# step by the first `run` containing "go test", and this step's does too,
# so moving it earlier would silently repoint three existing sync gates.
- name: Re-derive the published figures
id: figures
if: steps.changes.outputs.changed == 'true'
continue-on-error: true
env:
DEVCLOUD_UPDATE_DOCS: "1"
run: |
# pipefail, or sed's exit code is the step's: the updater refusing to
# invent a sentence would then report success and the PR would read as
# a clean sync. The runner's default shell is `bash -e`, not `bash -eo
# pipefail`, so this has to be said.
set -o pipefail
CGO_ENABLED=0 go test ./cmd/devcloud/ \
-run 'TestUpdatePublishedFigures' -v \
| sed -n '/^\*\*[0-9]* of /,/^$/p;/^| Figure/,/^$/p;/^PROSE REQUIRED/,$p' \
> /tmp/figures.md
cat /tmp/figures.md
# The diff is whole-tree whether upstream moved one model or ninety — a
# real refresh measured on 2026-09-06 changed 93 models and 134 generated
# files. Asking a reviewer to "review" that is asking for nothing. This
# reduces it to the question they actually have: which operations moved.
- name: Summarise the churn
if: steps.changes.outputs.changed == 'true'
run: |
{
echo "Automated weekly sync of AWS Smithy models from \`aws-sdk-go-v2\`."
echo
echo "**In-job test result: \`${{ steps.tests.outcome }}\`.**"
echo
echo "A \`failure\` is expected when upstream added or removed an"
echo "operation: the published-figure gate over \`docs/coverage.md\` fails"
echo "on purpose so a human looks at a coverage change. The figures"
echo "below are already re-derived and committed to this PR."
echo
echo "This PR's own \`ci\`, \`compat\` and \`codegen-drift\` runs are the"
echo "gate on merging."
echo
echo "---"
echo
echo "**Published figures: \`${{ steps.figures.outcome }}\`.**"
echo
echo "A \`failure\` means a change needs a sentence rather than a"
echo "number — read the PROSE REQUIRED block below and write it"
echo "before merging."
echo
cat /tmp/figures.md
echo
echo "---"
echo
python3 scripts/model_churn.py --upstream
echo
echo "<sub>Summary from \`scripts/model_churn.py\`; re-derive with"
echo "\`python3 scripts/model_churn.py --upstream\`.</sub>"
} > /tmp/sync-pr-body.md
cat /tmp/sync-pr-body.md
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Create Pull Request
if: steps.changes.outputs.changed == 'true'
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8
with:
commit-message: "chore: sync Smithy models and regenerate code"
title: "chore: weekly Smithy model sync"
body-path: /tmp/sync-pr-body.md
branch: smithy-sync/weekly
delete-branch: true
# The PR now exists, so the failure can end the job. Without this the cron
# would report success every week no matter what upstream did — the same
# silent no-op scripts/download-smithy-models.sh was fixed to stop doing,
# traded for the one continue-on-error just removed.
#
# Both continue-on-error steps are read, not just the tests. A PROSE
# REQUIRED result means docs/coverage.md is wrong until someone writes a
# sentence, and reading only the test outcome would end the job green on
# the one failure mode this automation cannot fix for itself.
- name: Fail if the sync's tests failed
if: steps.tests.outcome == 'failure' || steps.figures.outcome == 'failure'
run: |
echo "::error::Smithy sync needs a look (tests=${{ steps.tests.outcome }}, figures=${{ steps.figures.outcome }}); see the PR opened by this run."
exit 1