-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Expand file tree
/
Copy pathcreate-merge-from-previous-release-branch-pr.yml
More file actions
144 lines (126 loc) · 6.24 KB
/
Copy pathcreate-merge-from-previous-release-branch-pr.yml
File metadata and controls
144 lines (126 loc) · 6.24 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
name: create-merge-from-previous-release-branch
on:
push:
branches: ["release/*"]
workflow_dispatch:
permissions: {}
jobs:
setup:
if: github.repository == 'opf/openproject'
runs-on: ubuntu-latest
outputs:
previous_release_branch: ${{ steps.find_release_branches.outputs.previous_branch }}
latest_release_branch: ${{ steps.find_release_branches.outputs.latest_branch }}
steps:
- id: find_release_branches
env:
GITHUB_TOKEN: ${{ secrets.OPENPROJECTCI_GH_CORE_PAT }}
GITHUB_REPOSITORY: ${{ github.repository }}
run: |
LATEST_BRANCHES=$(gh api --paginate \
"repos/$GITHUB_REPOSITORY/branches?protected=true&per_page=100" \
--jq '.[].name' | grep '^release/' | sort --version-sort | tail -2
)
LATEST_BRANCH=$(echo "$LATEST_BRANCHES" | tail -1)
PREVIOUS_BRANCH=$(echo "$LATEST_BRANCHES" | head -1)
if [ -z "$LATEST_BRANCH" ] || [ -z "$PREVIOUS_BRANCH" ]; then
echo "Invalid release branches found: latest=$LATEST_BRANCH, previous=$PREVIOUS_BRANCH"
exit 1
fi
echo "Found previous release branch: $PREVIOUS_BRANCH"
echo "previous_branch=${PREVIOUS_BRANCH}" >> $GITHUB_OUTPUT
echo "Found latest release branch: $LATEST_BRANCH"
echo "latest_branch=${LATEST_BRANCH}" >> $GITHUB_OUTPUT
merge-or-create-pr:
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref_name == needs.setup.outputs.previous_release_branch)
env:
RELEASE_BRANCH: ${{ needs.setup.outputs.latest_release_branch }}
PREVIOUS_RELEASE_BRANCH: ${{ needs.setup.outputs.previous_release_branch }}
permissions:
contents: write # for git push
pull-requests: write # for creating pull request
runs-on: ubuntu-latest
needs: setup
timeout-minutes: 5
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
ref: ${{ env.RELEASE_BRANCH }}
- name: Fetch both release branches with sufficient history
run: |
# Calculate a reasonable date to fetch from (e.g., 6 months ago)
SINCE_DATE=$(date -d '3 months ago' '+%Y-%m-%d')
echo "Fetching commits since: $SINCE_DATE"
# Fetch both branches with commits since the calculated date
git fetch --shallow-since="$SINCE_DATE" origin "$RELEASE_BRANCH" "$PREVIOUS_RELEASE_BRANCH" || {
echo "Shallow-since fetch failed, trying with depth strategy..."
# Fallback: Use progressive deepening
git fetch --depth=50 origin "$RELEASE_BRANCH" "$PREVIOUS_RELEASE_BRANCH"
for depth in 100 200 500 1000; do
if git merge-base --is-ancestor "origin/$PREVIOUS_RELEASE_BRANCH" "origin/$RELEASE_BRANCH" 2>/dev/null || \
git merge-base --is-ancestor "origin/$RELEASE_BRANCH" "origin/$PREVIOUS_RELEASE_BRANCH" 2>/dev/null || \
git merge-base "origin/$RELEASE_BRANCH" "origin/$PREVIOUS_RELEASE_BRANCH" >/dev/null 2>&1; then
echo "Found sufficient history at depth $depth"
break
fi
echo "Deepening to $depth commits..."
git fetch --deepen=$((depth-50)) origin "$RELEASE_BRANCH" "$PREVIOUS_RELEASE_BRANCH" || true
done
}
- name: Resolve bug in git https://stackoverflow.com/a/63879454/96823
run: git repack -d
- name: Verify we have sufficient history
run: |
echo "Checking if we can find merge-base between branches..."
if git merge-base "origin/$RELEASE_BRANCH" "origin/$PREVIOUS_RELEASE_BRANCH" >/dev/null 2>&1; then
MERGE_BASE=$(git merge-base "origin/$RELEASE_BRANCH" "origin/$PREVIOUS_RELEASE_BRANCH")
echo "✅ Found merge-base: $MERGE_BASE"
else
echo "⚠️ Could not find merge-base, operations may be limited"
fi
echo "Branch $RELEASE_BRANCH has $(git rev-list --count origin/$RELEASE_BRANCH) commits"
echo "Branch $PREVIOUS_RELEASE_BRANCH has $(git rev-list --count origin/$PREVIOUS_RELEASE_BRANCH) commits"
- name: Create local tracking branches
run: |
git branch "$PREVIOUS_RELEASE_BRANCH" "origin/$PREVIOUS_RELEASE_BRANCH" || true
git branch "$RELEASE_BRANCH" "origin/$RELEASE_BRANCH" || true
- name: Required git config
run: |
git config user.name "OpenProject Actions CI"
git config user.email "operations+ci@openproject.com"
- name: Show diff
run: git diff ..."$PREVIOUS_RELEASE_BRANCH"
- name: Try merging or create a PR
run: |
if git diff --exit-code --quiet ..."$PREVIOUS_RELEASE_BRANCH"; then
echo "Nothing to merge from $PREVIOUS_RELEASE_BRANCH into $RELEASE_BRANCH"
else
if git merge --no-edit --no-ff "$PREVIOUS_RELEASE_BRANCH" && git push origin "$RELEASE_BRANCH"; then
echo "Successfully merged $PREVIOUS_RELEASE_BRANCH into $RELEASE_BRANCH and pushed"
else
# Close all previous PRs with label
pr_numbers=$(gh pr list --label merge-previous-release-branch --json number --jq='.[].number')
for pr_number in $pr_numbers; do
gh pr close "$pr_number" --delete-branch
done
pr_body=$(
echo 'Created by GitHub action'
for pr_number in $pr_numbers; do
echo "Replaces #$pr_number"
done
)
TEMP_BRANCH="merge-$PREVIOUS_RELEASE_BRANCH-$(date "+%Y%m%d%H%M%S")"
git branch "$TEMP_BRANCH" "$PREVIOUS_RELEASE_BRANCH"
git push origin "$TEMP_BRANCH"
gh pr create \
--base "$RELEASE_BRANCH" \
--head "$TEMP_BRANCH" \
--title "Merge $PREVIOUS_RELEASE_BRANCH into $RELEASE_BRANCH" \
--body "$pr_body" \
--label merge-previous-release-branch
echo "Created a PR to merge $PREVIOUS_RELEASE_BRANCH ($TEMP_BRANCH) into $RELEASE_BRANCH"
fi
fi
env:
GITHUB_TOKEN: ${{ secrets.OPENPROJECTCI_GH_CORE_PAT }}