-
Notifications
You must be signed in to change notification settings - Fork 2.2k
157 lines (138 loc) · 5.33 KB
/
Copy pathsync-release-branch.yml
File metadata and controls
157 lines (138 loc) · 5.33 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
name: Sync Docker release branch
concurrency:
group: ${{ github.workflow }}-${{ inputs.release_branch }}
cancel-in-progress: false
permissions:
contents: read
on:
workflow_dispatch:
inputs:
release_branch:
description: Release branch to sync, for example 29.x
required: true
type: string
tag:
description: Tag to sync from, for example v29.6.0
required: true
type: string
dry_run:
description: Merge but don't push
required: true
default: false
type: boolean
jobs:
sync-release-branch:
runs-on: ubuntu-24.04
permissions:
contents: write
actions: write
outputs:
base_sha: ${{ steps.sync.outputs.base_sha }}
has_changes: ${{ steps.sync.outputs.has_changes }}
temporary_branch: ${{ steps.sync.outputs.temporary_branch }}
temporary_sha: ${{ steps.sync.outputs.temporary_sha }}
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
- name: Validate
env:
BRANCH: ${{ github.ref_name }}
RELEASE_BRANCH: ${{ inputs.release_branch }}
run: |
if [ "$BRANCH" != "master" ]; then
echo "::error::This workflow is expected to be run on master, not $BRANCH"
exit 1
fi
if [ "$RELEASE_BRANCH" = "master" ]; then
echo "::error::The release branch must not be master"
exit 1
fi
if ! [[ "$RELEASE_BRANCH" =~ ^[0-9]+\.[x0-9]+$ ]]; then
echo "::error::Invalid release branch name: '$RELEASE_BRANCH'. Expected format: 29.x"
exit 1
fi
- name: Configure git author
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Sync release branch to tag range
id: sync
env:
DRY_RUN: ${{ inputs.dry_run }}
RELEASE_BRANCH: ${{ inputs.release_branch }}
RUN_ATTEMPT: ${{ github.run_attempt }}
RUN_ID: ${{ github.run_id }}
TAG: ${{ inputs.tag }}
run: |
set -o pipefail
base_sha=$(git rev-parse "origin/$RELEASE_BRANCH")
temporary_branch="process/sync-release-branch/$RUN_ID-$RUN_ATTEMPT"
echo "base_sha=$base_sha" >> "$GITHUB_OUTPUT"
echo "temporary_branch=$temporary_branch" >> "$GITHUB_OUTPUT"
# Keep the master checkout unchanged so scripts run from the dispatched revision.
release_worktree="$RUNNER_TEMP/release-branch"
git worktree add --detach "$release_worktree" "$base_sha"
cd "$release_worktree"
tags_file=$(mktemp)
"$GITHUB_WORKSPACE/scripts/unmerged-tags" \
"origin/$RELEASE_BRANCH" \
"$TAG" \
> "$tags_file"
echo >> "$GITHUB_STEP_SUMMARY"
echo "## Tags to sync" >> "$GITHUB_STEP_SUMMARY"
echo >> "$GITHUB_STEP_SUMMARY"
sed 's/^/- /' "$tags_file" >> "$GITHUB_STEP_SUMMARY"
xargs -r "$GITHUB_WORKSPACE/scripts/sync-branch" < "$tags_file" | tee -a "$GITHUB_STEP_SUMMARY"
if [[ "$DRY_RUN" == "true" ]]; then
echo "has_changes=false" >> "$GITHUB_OUTPUT"
exit 0
fi
if [[ $(git rev-parse HEAD) == $(git rev-parse "origin/$RELEASE_BRANCH") ]]; then
echo "has_changes=false" >> "$GITHUB_OUTPUT"
echo "No changes to push"
exit 0
fi
echo "has_changes=true" >> "$GITHUB_OUTPUT"
git push origin "HEAD:refs/heads/$temporary_branch"
echo "temporary_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
push-release-branch:
needs: sync-release-branch
if: ${{ !inputs.dry_run && needs.sync-release-branch.outputs.has_changes == 'true' }}
runs-on: ubuntu-24.04
environment: docker-releases
permissions:
contents: write
actions: write
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
- name: Push release branch
env:
BASE_SHA: ${{ needs.sync-release-branch.outputs.base_sha }}
RELEASE_BRANCH: ${{ inputs.release_branch }}
TEMPORARY_BRANCH: ${{ needs.sync-release-branch.outputs.temporary_branch }}
TEMPORARY_SHA: ${{ needs.sync-release-branch.outputs.temporary_sha }}
run: |
git fetch origin "$RELEASE_BRANCH"
current_sha=$(git rev-parse "origin/$RELEASE_BRANCH")
if [[ "$current_sha" != "$BASE_SHA" ]]; then
echo "$RELEASE_BRANCH changed from $BASE_SHA to $current_sha"
exit 1
fi
git fetch origin "$TEMPORARY_BRANCH"
current_temporary_sha=$(git rev-parse FETCH_HEAD)
if [[ "$current_temporary_sha" != "$TEMPORARY_SHA" ]]; then
echo "$TEMPORARY_BRANCH changed from $TEMPORARY_SHA to $current_temporary_sha"
exit 1
fi
git push origin "FETCH_HEAD:$RELEASE_BRANCH"
- name: Delete temporary branch
env:
TEMPORARY_BRANCH: ${{ needs.sync-release-branch.outputs.temporary_branch }}
run: git push origin --delete "$TEMPORARY_BRANCH"