@@ -36,26 +36,89 @@ jobs:
3636 path : cloudnative-pg
3737 repository : cloudnative-pg/cloudnative-pg
3838 sparse-checkout : api/v1
39+ # Full history is required to replay each upstream commit individually.
40+ fetch-depth : 0
3941
4042 - name : Setup Go
4143 uses : actions/setup-go@v6
4244 with :
4345 go-version-file : cloudnative-pg/go.mod
4446
45- - name : Copy types files from cloudnative-pg
47+ # Replay every upstream commit that touched the synced files as an individual
48+ # commit, reusing the original message and appending a
49+ # "(cherry picked from commit <sha>)" trailer (like `git cherry-pick -x`).
50+ # A literal cherry-pick is impossible because this repository rewrites the
51+ # module path and relocates the files to pkg/api/v1, so we reproduce each
52+ # upstream snapshot instead. The trailer doubles as the sync state anchor.
53+ - name : Sync API types from cloudnative-pg
54+ env :
55+ UPSTREAM : cloudnative-pg/cloudnative-pg
4656 run : |
47- rm -rf pkg/api/v1
48- mkdir -p pkg/api/v1
49- cp -v cloudnative-pg/api/v1/*_types.go pkg/api/v1
50- cp -v cloudnative-pg/api/v1/doc.go pkg/api/v1
51- cp -v cloudnative-pg/api/v1/groupversion_info.go pkg/api/v1
52- cp -v cloudnative-pg/api/v1/zz_*.go pkg/api/v1
53- cp -v cloudnative-pg/go.mod cloudnative-pg/go.sum .
54- sed -i '1 s|^.*$|module github.com/cloudnative-pg/api|' go.mod
55- go mod tidy
56- go vet ./...
57-
58- # We want to prevent the "include administrators" branch protection from blocking the commit,
57+ set -euo pipefail
58+
59+ git config user.name "CloudNativePG Automated Updates"
60+ git config user.email "noreply@cnpg.com"
61+
62+ # Find the last synced upstream commit recorded in our history. Our own
63+ # trailer is always the final line of the body, so take the last match
64+ # (upstream backport commits may carry their own cherry-pick line too).
65+ # The trailing hex run is the SHA regardless of the "<owner>/<repo>@"
66+ # prefix we add for cross-repo linking.
67+ LAST=$(git log --grep='cherry picked from commit' -n1 --pretty=%B \
68+ | grep -iE 'cherry picked from commit' \
69+ | tail -n1 \
70+ | grep -oiE '[0-9a-f]{7,40}' \
71+ | tail -n1) || true
72+
73+ # Build the list of upstream commits to replay, oldest first.
74+ if [ -n "${LAST:-}" ]; then
75+ mapfile -t COMMITS < <(git -C cloudnative-pg log --reverse --pretty=%H "$LAST..HEAD" -- api/v1 go.mod go.sum)
76+ else
77+ # Bootstrap: no anchor yet, seed from the current upstream HEAD only.
78+ mapfile -t COMMITS < <(git -C cloudnative-pg rev-parse HEAD)
79+ fi
80+
81+ if [ ${#COMMITS[@]} -eq 0 ]; then
82+ echo "Already up to date with upstream; nothing to sync."
83+ exit 0
84+ fi
85+
86+ for sha in "${COMMITS[@]}"; do
87+ git -C cloudnative-pg checkout -q "$sha" -- api/v1 go.mod go.sum
88+
89+ rm -rf pkg/api/v1
90+ mkdir -p pkg/api/v1
91+ cp -v cloudnative-pg/api/v1/*_types.go pkg/api/v1
92+ cp -v cloudnative-pg/api/v1/doc.go pkg/api/v1
93+ cp -v cloudnative-pg/api/v1/groupversion_info.go pkg/api/v1
94+ cp -v cloudnative-pg/api/v1/zz_*.go pkg/api/v1
95+ cp -v cloudnative-pg/go.mod cloudnative-pg/go.sum .
96+ sed -i '1 s|^.*$|module github.com/cloudnative-pg/api|' go.mod
97+ go mod tidy
98+ go vet ./...
99+
100+ git add pkg/api/v1 go.mod go.sum
101+ if git diff --cached --quiet; then
102+ echo "Upstream commit $sha has no net effect on synced files, skipping."
103+ continue
104+ fi
105+
106+ GIT_AUTHOR_NAME=$(git -C cloudnative-pg show -s --pretty=%an "$sha")
107+ GIT_AUTHOR_EMAIL=$(git -C cloudnative-pg show -s --pretty=%ae "$sha")
108+ GIT_AUTHOR_DATE=$(git -C cloudnative-pg show -s --pretty=%aI "$sha")
109+ export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
110+
111+ # Qualify bare "#NNNN" references so they link to the upstream repo
112+ # rather than to issues/PRs in this mirror. The negative lookbehind
113+ # keeps already-qualified refs (e.g. owner/repo#7) and "word#7" untouched.
114+ MSG=$(git -C cloudnative-pg show -s --pretty=%B "$sha" \
115+ | perl -pe 's{(?<![\w/])#(\d+)\b}{$ENV{UPSTREAM}#$1}g')
116+ git commit \
117+ -m "$MSG" \
118+ -m "(cherry picked from commit ${UPSTREAM}@${sha})"
119+ done
120+
121+ # We want to prevent the "include administrators" branch protection from blocking the push,
59122 # but it should be usually there to avoid accidental pushes to main.
60123 - name : Temporarily disable "include administrators" branch protection
61124 if : ${{ github.ref == 'refs/heads/main' }}
@@ -66,12 +129,8 @@ jobs:
66129 branch : main
67130 enforce_admins : false
68131
69- - uses : EndBug/add-and-commit@v10
70- with :
71- author_name : CloudNativePG Automated Updates
72- author_email : noreply@cnpg.com
73- message : ' chore: sync API'
74- add : pkg/api/v1 go.mod go.sum
132+ - name : Push synced commits
133+ run : git push origin "HEAD:${GITHUB_REF_NAME}"
75134
76135 - name : Enable "include administrators" branch protection
77136 uses : benjefferies/branch-protection-bot@v1.1.2
0 commit comments