-
Notifications
You must be signed in to change notification settings - Fork 4
239 lines (223 loc) · 8.58 KB
/
Copy pathbuild.yml
File metadata and controls
239 lines (223 loc) · 8.58 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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
name: Build
on:
push:
branches: [ master ]
paths:
- ".github/workflows/build.yml"
- "build.py"
- "release.py"
- "releases.json"
pull_request:
branches: [ master ]
paths:
- ".github/workflows/build.yml"
- "build.py"
- "release.py"
- "releases.json"
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
generate-matrix:
permissions:
contents: read
runs-on: ubuntu-latest
outputs:
build-matrix: ${{ steps.set-matrix.outputs.build-matrix }}
steps:
- uses: actions/checkout@v7
- name: Generate build matrix from releases.json
id: set-matrix
run: |
MATRIX=$(python3 << 'PYEOF'
import json
with open('releases.json') as f:
releases = json.load(f)
platforms = [
{'platform': 'linux-amd64', 'os': 'linux', 'arch': 'amd64', 'runner': 'ubuntu-22.04'},
{'platform': 'linux-arm64', 'os': 'linux', 'arch': 'arm64', 'runner': 'ubuntu-22.04-arm'},
{'platform': 'macos-amd64', 'os': 'macos', 'arch': 'amd64', 'runner': 'macos-15-intel'},
{'platform': 'macos-arm64', 'os': 'macos', 'arch': 'arm64', 'runner': 'macos-14'},
{'platform': 'windows-amd64', 'os': 'windows', 'arch': 'amd64', 'runner': 'windows-latest'},
{'platform': 'windows-arm64', 'os': 'windows', 'arch': 'arm64', 'runner': 'windows-11-arm'},
]
include = [{'clang-version': v, 'release': r} for v, r in releases.items()]
include.extend(platforms)
matrix = {
'clang-version': sorted(releases.keys(), key=int),
'platform': [p['platform'] for p in platforms],
'include': include,
}
print(json.dumps(matrix))
PYEOF
)
printf 'build-matrix=%s\n' "$MATRIX" >> "$GITHUB_OUTPUT"
build:
needs: generate-matrix
permissions: {}
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.generate-matrix.outputs.build-matrix) }}
runs-on: ${{ matrix.runner }}
env:
RELEASE: '${{ matrix.release }}'
suffix: '${{ matrix.clang-version }}_${{ matrix.os }}-${{ matrix.arch }}'
steps:
- name: Download build script and patches
# We download a tarball of this repo, as the presence of a .git directory leaks
# The commit hash of this repository into the clang binaries
shell: bash
run: curl -sL https://github.com/${{ github.repository }}/archive/${{ github.ref }}.tar.gz | tar xvz --strip 1
- name: Build
shell: bash
run: python3 build.py --version "${{ matrix.clang-version }}" --platform ${{ matrix.platform }}
- name: Upload artifacts
uses: actions/upload-artifact@v7
with:
name: clang-tools-${{ matrix.release }}-${{ env.suffix }}
path: |
${{ matrix.release }}/build/**/clang-*-${{ env.suffix }}*
${{ matrix.release }}/build/**/llvm-*-${{ env.suffix }}*
${{ matrix.release }}/build/**/SHA512SUMS
# ** covers both bin/ (Linux/macOS) and MinSizeRel/bin/ (Windows)
# clang-* matches clang-format, clang-tidy, clang-query, clang-scan-deps, etc.
# llvm-* matches llvm-cov, llvm-profdata, llvm-symbolizer
retention-days: 3
test-release:
permissions: {}
strategy:
matrix:
include:
- os: linux
arch: amd64
runner: ubuntu-22.04
- os: linux
arch: arm64
runner: ubuntu-22.04-arm
- os: macos
arch: amd64
runner: macos-15-intel
- os: macos
arch: arm64
runner: macos-14
- os: windows
arch: amd64
runner: windows-latest
- os: windows
arch: arm64
runner: windows-11-arm
runs-on: ${{ matrix.runner }}
needs: build
env:
suffix: '_${{ matrix.os }}-${{ matrix.arch }}'
steps:
- name: Download artifacts
uses: actions/download-artifact@v8
with:
path: artifacts
pattern: '**/*${{ env.suffix }}'
- name: List files (Linux, macOS)
if: ${{ matrix.os == 'linux' || matrix.os == 'macos' }}
run: ls -laR artifacts/
- name: List files (Windows)
if: ${{ matrix.os == 'windows' }}
run: |
Get-ChildItem -Recurse artifacts | Format-List
draft-release:
if: github.event_name != 'pull_request'
permissions:
contents: write
runs-on: ubuntu-22.04
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Get short SHA
id: get-sha
run: echo "short_sha=${GITHUB_SHA:0:8}" >> $GITHUB_OUTPUT
- name: Get date
id: get-date
run: echo "date=$(date -u +'%Y.%m.%d')" >> $GITHUB_OUTPUT
- name: Download artifacts
uses: actions/download-artifact@v8
- name: Generate versions.json and release notes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: "${{ steps.get-date.outputs.date }}-${{ steps.get-sha.outputs.short_sha }}"
REPO: "${{ github.repository }}"
run: |
python3 release.py --tag "$TAG"
# Append Full Changelog link if a previous release exists
prev_tag=$(gh release list --limit 1 --json tagName --jq '.[0].tagName // empty')
if [[ -n "$prev_tag" ]]; then
echo "Previous release tag: $prev_tag"
echo "" >> release-notes.md
echo "**Full Changelog**: https://github.com/${REPO}/compare/${prev_tag}...${TAG}" >> release-notes.md
else
echo "No previous release found."
fi
- name: List files
run: ls -laR .
- name: Workaround - delete all files over 2G, above github release file upload limit
run: find . -type f -size +2G -exec rm -v {} \;
- name: Create draft release and upload assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: "${{ steps.get-date.outputs.date }}-${{ steps.get-sha.outputs.short_sha }}"
run: |
set -euo pipefail
# Create draft release with auto-generated notes (ignore error if already exists)
gh release create "$TAG" \
--draft \
--prerelease \
--title "$TAG" \
--notes-file release-notes.md \
2>/dev/null || true
# Upload a single file with retry + exponential backoff
upload_with_retry() {
local file="$1"
local max_retries=5
local delay=10
for i in $(seq 1 $max_retries); do
if gh release upload "$TAG" "$file" 2>&1; then
echo "::notice::Uploaded: $file"
return 0
fi
if [[ $i -ge $max_retries ]]; then
echo "::error::Failed to upload $file after $max_retries attempts"
return 1
fi
echo "::warning::Upload failed for $file (attempt $i/$max_retries). Retrying in ${delay}s..."
sleep "$delay"
delay=$((delay * 2))
done
}
# Combine all per-artifact SHA512SUMS into a single file at the workspace root.
# This mirrors the common open-source convention (e.g. Node.js SHASUMS256.txt)
# and avoids GitHub Release asset name collisions.
combined_sha="SHA512SUMS"
find clang-tools-* -name SHA512SUMS -type f -print0 | xargs -0 cat > "$combined_sha"
echo "Created combined $(wc -l < "$combined_sha")-entry $combined_sha"
# Remove the per-artifact SHA512SUMS files so they are not uploaded individually.
find clang-tools-* -name SHA512SUMS -type f -delete
# Collect all files and upload one-by-one with a small delay
mapfile -t files < <(find clang-tools-* -type f)
if [[ ${#files[@]} -eq 0 ]]; then
echo "::warning::No files found to upload"
exit 0
fi
echo "Found ${#files[@]} files to upload"
failed=0
# Upload top-level metadata files first (no filename conflicts)
upload_with_retry "versions.json" || failed=1
upload_with_retry "SHA512SUMS" || failed=1
for file in "${files[@]}"; do
upload_with_retry "$file" || failed=1
sleep 1
done
if [[ $failed -ne 0 ]]; then
echo "::error::Some uploads failed. Check the logs above."
exit 1
fi
echo "::notice::All ${#files[@]} files uploaded successfully."