-
Notifications
You must be signed in to change notification settings - Fork 4
156 lines (135 loc) · 6.45 KB
/
Copy pathsync.yaml
File metadata and controls
156 lines (135 loc) · 6.45 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
# This workflow will sync the API types from the cloudnative-pg repository to the API repository, and
# tidy the go.mod file.
# It is supposed to be triggered by a repository_dispatch event whenever the cloudnative-pg api is updated,
# but can also be triggered manually using the "Sync API" workflow_dispatch event.
name: Sync API
on:
workflow_dispatch:
repository_dispatch:
types: [ sync-api ]
permissions: read-all
# A release dispatches a tag-carrying sync while the push to main triggers a
# second, tag-less sync. Serialize them so they don't race on the commit to main
# and the tag-carrying run tags the already-synced commit.
concurrency:
group: sync-api
cancel-in-progress: false
jobs:
sync:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout API repository
uses: actions/checkout@v7
with:
token: ${{ secrets.REPO_PAT }}
- name: Checkout cloudnative-pg repository
uses: actions/checkout@v7
with:
path: cloudnative-pg
repository: cloudnative-pg/cloudnative-pg
sparse-checkout: api/v1
# Full history is required to replay each upstream commit individually.
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version-file: cloudnative-pg/go.mod
# Replay every upstream commit that touched the synced files as an individual
# commit, reusing the original message and appending a
# "(cherry picked from commit <sha>)" trailer (like `git cherry-pick -x`).
# A literal cherry-pick is impossible because this repository rewrites the
# module path and relocates the files to pkg/api/v1, so we reproduce each
# upstream snapshot instead. The trailer doubles as the sync state anchor.
- name: Sync API types from cloudnative-pg
env:
UPSTREAM: cloudnative-pg/cloudnative-pg
run: |
set -euo pipefail
git config user.name "CloudNativePG Automated Updates"
git config user.email "noreply@cnpg.com"
# Find the last synced upstream commit recorded in our history. Our own
# trailer is always the final line of the body, so take the last match
# (upstream backport commits may carry their own cherry-pick line too).
# The trailing hex run is the SHA regardless of the "<owner>/<repo>@"
# prefix we add for cross-repo linking.
LAST=$(git log --grep='cherry picked from commit' -n1 --pretty=%B \
| grep -iE 'cherry picked from commit' \
| tail -n1 \
| grep -oiE '[0-9a-f]{7,40}' \
| tail -n1) || true
# Build the list of upstream commits to replay, oldest first.
if [ -n "${LAST:-}" ]; then
mapfile -t COMMITS < <(git -C cloudnative-pg log --reverse --pretty=%H "$LAST..HEAD" -- api/v1 go.mod go.sum)
else
# Bootstrap: no anchor yet, seed from the current upstream HEAD only.
mapfile -t COMMITS < <(git -C cloudnative-pg rev-parse HEAD)
fi
if [ ${#COMMITS[@]} -eq 0 ]; then
echo "Already up to date with upstream; nothing to sync."
exit 0
fi
for sha in "${COMMITS[@]}"; do
git -C cloudnative-pg checkout -q "$sha" -- api/v1 go.mod go.sum
rm -rf pkg/api/v1
mkdir -p pkg/api/v1
cp -v cloudnative-pg/api/v1/*_types.go pkg/api/v1
cp -v cloudnative-pg/api/v1/doc.go pkg/api/v1
cp -v cloudnative-pg/api/v1/groupversion_info.go pkg/api/v1
cp -v cloudnative-pg/api/v1/zz_*.go pkg/api/v1
cp -v cloudnative-pg/go.mod cloudnative-pg/go.sum .
sed -i '1 s|^.*$|module github.com/cloudnative-pg/api|' go.mod
go mod tidy
go vet ./...
git add pkg/api/v1 go.mod go.sum
if git diff --cached --quiet; then
echo "Upstream commit $sha has no net effect on synced files, skipping."
continue
fi
GIT_AUTHOR_NAME=$(git -C cloudnative-pg show -s --pretty=%an "$sha")
GIT_AUTHOR_EMAIL=$(git -C cloudnative-pg show -s --pretty=%ae "$sha")
GIT_AUTHOR_DATE=$(git -C cloudnative-pg show -s --pretty=%aI "$sha")
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
# Qualify bare "#NNNN" references so they link to the upstream repo
# rather than to issues/PRs in this mirror. The negative lookbehind
# keeps already-qualified refs (e.g. owner/repo#7) and "word#7" untouched.
MSG=$(git -C cloudnative-pg show -s --pretty=%B "$sha" \
| perl -pe 's{(?<![\w/])#(\d+)\b}{$ENV{UPSTREAM}#$1}g')
git commit \
-m "$MSG" \
-m "(cherry picked from commit ${UPSTREAM}@${sha})"
done
# We want to prevent the "include administrators" branch protection from blocking the push,
# but it should be usually there to avoid accidental pushes to main.
- name: Temporarily disable "include administrators" branch protection
if: ${{ github.ref == 'refs/heads/main' }}
id: disable_include_admins
uses: benjefferies/branch-protection-bot@v1.1.2
with:
access_token: ${{ secrets.REPO_PAT }}
branch: main
enforce_admins: false
- name: Push synced commits
run: git push origin "HEAD:${GITHUB_REF_NAME}"
- name: Enable "include administrators" branch protection
uses: benjefferies/branch-protection-bot@v1.1.2
if: ${{ always() && github.ref == 'refs/heads/main' }}
with:
access_token: ${{ secrets.REPO_PAT }}
branch: main
enforce_admins: ${{ steps.disable_include_admins.outputs.initial_status }}
# When the sync is triggered by a release, the cloudnative-pg release-tag
# workflow passes the release tag in the dispatch payload. Tag the freshly
# synced commit so the API repository keeps the same tags as cloudnative-pg.
- name: Tag the synced release
if: ${{ github.event_name == 'repository_dispatch' && github.event.client_payload.tag != '' }}
env:
TAG: ${{ github.event.client_payload.tag }}
run: |
if git ls-remote --tags origin "refs/tags/${TAG}" | grep -q .; then
echo "Tag ${TAG} already exists, nothing to do."
exit 0
fi
git tag "${TAG}"
git push origin "${TAG}"