-
Notifications
You must be signed in to change notification settings - Fork 4
150 lines (135 loc) · 5.51 KB
/
backport.yaml
File metadata and controls
150 lines (135 loc) · 5.51 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
name: Auto Backport from Upstream
on:
schedule:
- cron: "*/30 * * * *"
workflow_dispatch:
inputs:
force_sync:
description: "Force sync all recent commits (ignores watermark)"
required: false
default: "false"
concurrency:
group: auto-backport
cancel-in-progress: false
env:
SOURCE_REPO: apache/apisix-ingress-controller
SOURCE_BRANCH: master
TARGET_BRANCH: ${{ github.event.repository.default_branch || 'master' }}
MAX_COMMITS_PER_RUN: 5
jobs:
auto-backport:
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
actions: write
contents: write
pull-requests: write
issues: write
repository-projects: write
env:
GH_TOKEN: ${{ secrets.BACKPORT_PAT }}
GITHUB_REPOSITORY: ${{ github.repository }}
FORCE_SYNC: ${{ github.event.inputs.force_sync || 'false' }}
steps:
- name: Checkout target repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.BACKPORT_PAT }}
- name: Show run configuration
run: |
echo "Force sync: $FORCE_SYNC"
echo "Source repo: $SOURCE_REPO"
echo "Source branch: $SOURCE_BRANCH"
echo "Target branch: $TARGET_BRANCH"
- name: Configure git identity
run: |
git config --global user.name "backport-bot[bot]"
git config --global user.email "backport-bot[bot]@users.noreply.github.com"
- name: Add upstream remote
run: |
git remote add upstream "https://github.com/${SOURCE_REPO}.git" 2>/dev/null || true
git remote set-url upstream "https://github.com/${SOURCE_REPO}.git"
- name: Fetch upstream branch
run: |
git fetch --prune --no-tags upstream "${SOURCE_BRANCH}"
- name: Read last processed commit watermark
id: watermark
run: |
LAST_SHA=$(gh variable get LAST_BACKPORT_SHA -R "${GITHUB_REPOSITORY}" --json value --jq '.value' 2>/dev/null || echo "")
if [[ -z "$LAST_SHA" || "$FORCE_SYNC" == "true" ]]; then
LAST_SHA=$(git log "upstream/${SOURCE_BRANCH}" --since="7 days ago" --format="%H" | tail -n 1)
fi
echo "last_sha=${LAST_SHA}" >> "$GITHUB_OUTPUT"
echo "Last processed SHA: ${LAST_SHA:-<none>}"
- name: Collect new commits
id: collect_commits
run: |
LAST_SHA="${{ steps.watermark.outputs.last_sha }}"
if [[ -n "$LAST_SHA" ]]; then
COMMITS=$(git log "upstream/${SOURCE_BRANCH}" ^"$LAST_SHA" --format="%H" --reverse | head -"${MAX_COMMITS_PER_RUN}")
else
COMMITS=$(git log "upstream/${SOURCE_BRANCH}" -1 --format="%H")
fi
{
echo "commits<<EOF"
printf '%s\n' "$COMMITS"
echo "EOF"
} >> "$GITHUB_OUTPUT"
if [[ -z "$COMMITS" ]]; then
COUNT=0
else
COUNT=$(printf '%s\n' "$COMMITS" | grep -c '[0-9a-f]')
fi
echo "count=${COUNT}" >> "$GITHUB_OUTPUT"
echo "Commits to process: ${COUNT}"
- name: Ensure labels exist
run: |
gh label create backport --color EDEDED --description "Automated backport" -R "${GITHUB_REPOSITORY}" 2>/dev/null || true
gh label create automated --color EDEDED --description "Created by automation" -R "${GITHUB_REPOSITORY}" 2>/dev/null || true
gh label create backport-failed --color D73A4A --description "Backport failed" -R "${GITHUB_REPOSITORY}" 2>/dev/null || true
gh label create needs-manual-action --color FBCA04 --description "Manual intervention required" -R "${GITHUB_REPOSITORY}" 2>/dev/null || true
gh label create conflicts --color D93F0B --description "Contains merge conflicts" -R "${GITHUB_REPOSITORY}" 2>/dev/null || true
- name: Process commits
if: steps.collect_commits.outputs.count != '0'
env:
GH_TOKEN: ${{ github.token }}
run: |
chmod +x .github/scripts/backport-commit.sh
SUCCESS=0
FAILURE=0
LAST_PROCESSED=""
while IFS= read -r COMMIT; do
[[ -z "$COMMIT" ]] && continue
if .github/scripts/backport-commit.sh "$COMMIT"; then
SUCCESS=$((SUCCESS + 1))
LAST_PROCESSED="$COMMIT"
else
echo "Commit ${COMMIT} failed to backport"
FAILURE=$((FAILURE + 1))
fi
done <<< "${{ steps.collect_commits.outputs.commits }}"
echo "SUCCESS_COUNT=$SUCCESS" >> "$GITHUB_ENV"
echo "FAILURE_COUNT=$FAILURE" >> "$GITHUB_ENV"
echo "LAST_PROCESSED_SHA=$LAST_PROCESSED" >> "$GITHUB_ENV"
- name: Update watermark
if: env.LAST_PROCESSED_SHA != ''
run: |
if [[ "${FAILURE_COUNT:-0}" == "0" ]]; then
gh variable set LAST_BACKPORT_SHA -b "${LAST_PROCESSED_SHA}" -R "${GITHUB_REPOSITORY}"
else
echo "Failures detected; watermark will not be updated."
fi
- name: Summary
run: |
echo "Successful cherry-picks: ${SUCCESS_COUNT:-0}"
echo "Failed cherry-picks: ${FAILURE_COUNT:-0}"
echo "Last processed SHA: ${LAST_PROCESSED_SHA:-none}"
{
echo "# Backport Summary"
echo
echo "- Successful: ${SUCCESS_COUNT:-0}"
echo "- Failed: ${FAILURE_COUNT:-0}"
echo "- Last processed: ${LAST_PROCESSED_SHA:-none}"
echo "- Force sync: ${FORCE_SYNC}"
} >> "$GITHUB_STEP_SUMMARY"