Skip to content

Commit 07510c5

Browse files
committed
chore: Add release automation infrastructure
1 parent 32d2cd1 commit 07510c5

File tree

7 files changed

+142
-485
lines changed

7 files changed

+142
-485
lines changed

.github/workflows/rc.yml

Lines changed: 102 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -15,81 +15,130 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717

18-
name: Release Candidate
19-
18+
name: RC
2019
on:
2120
push:
2221
tags:
23-
- 'v*-rc*'
22+
- '*-rc*'
23+
24+
concurrency:
25+
group: ${{ github.repository }}-${{ github.head_ref || github.sha }}-${{ github.workflow }}
26+
cancel-in-progress: true
27+
permissions:
28+
contents: read
2429

2530
jobs:
26-
build-source-tarball:
31+
archive:
32+
name: Archive
2733
runs-on: ubuntu-latest
28-
34+
timeout-minutes: 5
2935
steps:
30-
- name: Checkout repository
36+
- name: Checkout
3137
uses: actions/checkout@v4
3238

33-
- name: Extract version from tag
34-
id: extract_version
39+
- name: Prepare for tag
40+
if: github.ref_type == 'tag'
3541
run: |
36-
TAG_NAME=${GITHUB_REF#refs/tags/}
37-
echo "tag_name=${TAG_NAME}" >> $GITHUB_OUTPUT
38-
VERSION=$(echo ${TAG_NAME} | sed 's/^v//' | sed 's/-rc.*$//')
39-
RC=$(echo ${TAG_NAME} | sed 's/.*-rc//')
40-
echo "version=${VERSION}" >> $GITHUB_OUTPUT
41-
echo "rc=${RC}" >> $GITHUB_OUTPUT
42-
echo "release_id=apache-iceberg-cpp-${VERSION}-rc${RC}" >> $GITHUB_OUTPUT
42+
version=${GITHUB_REF_NAME#v}
43+
version=${version%-rc*}
44+
rc=${GITHUB_REF_NAME##*-rc}
45+
echo "VERSION=${version}" >> ${GITHUB_ENV}
46+
echo "RC=${rc}" >> ${GITHUB_ENV}
47+
echo "VERSION=${version}"
48+
echo "RC=${rc}"
4349
44-
- name: Install dependencies
50+
- name: Archive
4551
run: |
46-
sudo apt-get update
47-
sudo apt-get install -y cmake build-essential
52+
id="apache-iceberg-cpp-${VERSION}-rc${RC}"
53+
tar_gz="${id}.tar.gz"
54+
echo "TAR_GZ=${tar_gz}" >> ${GITHUB_ENV}
55+
git archive HEAD --prefix "${id}/" --output "${tar_gz}"
56+
sha512sum "${tar_gz}" > "${tar_gz}.sha512"
4857
49-
- name: Create source tarball
58+
- name: Audit
5059
run: |
51-
# Create archive with git
52-
git archive --format=tar.gz --output="${{ steps.extract_version.outputs.release_id }}.tar.gz" --prefix="${{ steps.extract_version.outputs.release_id }}/" HEAD
53-
54-
# Generate SHA512 checksum
55-
sha512sum "${{ steps.extract_version.outputs.release_id }}.tar.gz" > "${{ steps.extract_version.outputs.release_id }}.tar.gz.sha512"
60+
dev/release/run_rat.sh "${TAR_GZ}"
5661
57-
# Verify the tarball can be extracted and built
58-
tar -xzf "${{ steps.extract_version.outputs.release_id }}.tar.gz"
59-
cd "${{ steps.extract_version.outputs.release_id }}"
62+
- uses: actions/upload-artifact@v4
63+
with:
64+
name: archive
65+
path: |
66+
apache-iceberg-cpp-*
6067
61-
# Basic build test
62-
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
63-
cmake --build build --parallel $(nproc)
68+
verify:
69+
name: Verify
70+
needs:
71+
- archive
72+
runs-on: ${{ matrix.os }}
73+
strategy:
74+
fail-fast: false
75+
matrix:
76+
os:
77+
- macos-latest
78+
- ubuntu-latest
79+
# - windows-latest
80+
steps:
81+
- name: Install C++ Build Tools (Ubuntu)
82+
if: runner.os == 'Linux'
83+
run: |
84+
sudo apt-get update
85+
sudo apt-get install -y build-essential cmake ninja-build libssl-dev
6486
65-
- name: Run license check
87+
- name: Install C++ Build Tools (macOS)
88+
if: runner.os == 'macOS'
6689
run: |
67-
# Extract the tarball if not already extracted
68-
if [ ! -d "${{ steps.extract_version.outputs.release_id }}" ]; then
69-
tar -xzf "${{ steps.extract_version.outputs.release_id }}.tar.gz"
70-
fi
90+
brew install cmake ninja openssl
7191
72-
cd "${{ steps.extract_version.outputs.release_id }}"
73-
dev/release/run_rat.sh .
92+
- name: Checkout
93+
uses: actions/checkout@v4
7494

75-
- name: Create GitHub Release
76-
uses: softprops/action-gh-release@v1
95+
- uses: actions/download-artifact@v4
7796
with:
78-
tag_name: ${{ steps.extract_version.outputs.tag_name }}
79-
name: Apache Iceberg C++ ${{ steps.extract_version.outputs.version }} RC${{ steps.extract_version.outputs.rc }}
80-
prerelease: true
81-
draft: false
82-
files: |
83-
${{ steps.extract_version.outputs.release_id }}.tar.gz
84-
${{ steps.extract_version.outputs.release_id }}.tar.gz.sha512
97+
name: archive
98+
99+
- name: Verify
100+
run: |
101+
tar_gz=$(echo apache-iceberg-cpp-*.tar.gz)
102+
version=${tar_gz#apache-iceberg-cpp-}
103+
version=${version%.tar.gz}
104+
version=${version%%-rc*}
105+
if [ "${GITHUB_REF_TYPE}" = "tag" ]; then
106+
rc=${GITHUB_REF_NAME##*-rc}
107+
else
108+
rc=100
109+
fi
110+
echo "VERSION=${version}"
111+
echo "RC=${rc}"
112+
# The verify_rc.sh script will untar and
113+
# run cmake, build, tests (ctest) and install
114+
VERIFY_SIGN=0 VERIFY_DOWNLOAD=0 dev/release/verify_rc.sh "${version}" "${rc}"
85115
env:
86116
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
87117

88-
- name: Upload artifacts
89-
uses: actions/upload-artifact@v4
118+
upload:
119+
name: Upload
120+
if: github.ref_type == 'tag'
121+
needs:
122+
- verify
123+
runs-on: ubuntu-latest
124+
permissions:
125+
contents: write
126+
steps:
127+
- name: Checkout
128+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
129+
130+
- uses: actions/download-artifact@v4
90131
with:
91-
name: release-candidate-${{ steps.extract_version.outputs.version }}-rc${{ steps.extract_version.outputs.rc }}
92-
path: |
93-
${{ steps.extract_version.outputs.release_id }}.tar.gz
94-
${{ steps.extract_version.outputs.release_id }}.tar.gz.sha512
95-
retention-days: 30
132+
name: archive
133+
134+
- name: Upload
135+
run: |
136+
gh release create ${GITHUB_REF_NAME} \
137+
--prerelease \
138+
--title "Apache Iceberg C++ ${GITHUB_REF_NAME}" \
139+
--generate-notes \
140+
--verify-tag \
141+
apache-iceberg-cpp-*.tar.gz \
142+
apache-iceberg-cpp-*.tar.gz.sha*
143+
env:
144+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

dev/release/README.md

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1-
<!---
2-
Licensed to the Apache Software Foundation (ASF) under one
3-
or more contributor license agreements. See the NOTICE file
4-
distributed with this work for additional information
5-
regarding copyright ownership. The ASF licenses this file
6-
to you under the Apache License, Version 2.0 (the
7-
"License"); you may not use this file except in compliance
8-
with the License. You may obtain a copy of the License at
9-
http://www.apache.org/licenses/LICENSE-2.0
10-
Unless required by applicable law or agreed to in writing,
11-
software distributed under the License is distributed on an
12-
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13-
KIND, either express or implied. See the License for the
14-
specific language governing permissions and limitations
15-
under the License.
1+
<!--
2+
~ Licensed to the Apache Software Foundation (ASF) under one
3+
~ or more contributor license agreements. See the NOTICE file
4+
~ distributed with this work for additional information
5+
~ regarding copyright ownership. The ASF licenses this file
6+
~ to you under the Apache License, Version 2.0 (the
7+
~ "License"); you may not use this file except in compliance
8+
~ with the License. You may obtain a copy of the License at
9+
~
10+
~ http://www.apache.org/licenses/LICENSE-2.0
11+
~
12+
~ Unless required by applicable law or agreed to in writing,
13+
~ software distributed under the License is distributed on an
14+
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
~ KIND, either express or implied. See the License for the
16+
~ specific language governing permissions and limitations
17+
~ under the License.
1618
-->
1719

1820
# Release
@@ -35,13 +37,13 @@ $ dev/release/release_rc.sh ${VERSION} ${RC}
3537
You can use a draft shown by release_rc.sh for the email.)
3638
```
3739

38-
Here is an example to release RC1:
40+
Here is an example to release RC0 of version 0.1.0:
3941

4042
```console
41-
$ GH_TOKEN=${YOUR_GITHUB_TOKEN} dev/release/release_rc.sh 0.1.0 1
43+
$ GH_TOKEN=${YOUR_GITHUB_TOKEN} dev/release/release_rc.sh 0.1.0 0
4244
```
4345

44-
The arguments of `release_rc.sh` are the version and the RC number. If RC1 has a problem, we'll increment the RC number such as RC2, RC3 and so on.
46+
The arguments of `release_rc.sh` are the version and the RC number. If RC0 has a problem, we'll increment the RC number such as RC1, RC2 and so on.
4547

4648
Requirements to run `release_rc.sh`:
4749

@@ -69,9 +71,7 @@ $ svn ci KEYS
6971

7072
### Publish
7173

72-
We need to do the following to publish a new release:
73-
74-
* Publish to apache.org
74+
We need to publish to apache.org to publish a new release.
7575

7676
Run `dev/release/release.sh` to publish to apache.org:
7777

dev/release/check_rat_report.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@
3030
exclude_globs_filename = sys.argv[1]
3131
xml_filename = sys.argv[2]
3232

33-
globs = [line.strip() for line in open(exclude_globs_filename, "r")]
33+
globs = []
34+
with open(exclude_globs_filename, "r") as f:
35+
for line in f:
36+
stripped_line = line.strip()
37+
if not stripped_line or stripped_line.startswith('#'):
38+
continue
39+
globs.append(stripped_line)
3440

3541
tree = ET.parse(xml_filename)
3642
root = tree.getroot()

dev/release/rat_exclude_files.txt

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,11 @@
1818
.gitignore
1919
LICENSE
2020
NOTICE
21-
CLAUDE.md
22-
README.md
23-
CONTRIBUTING.md
24-
CHANGELOG.md
25-
build/
26-
dist/
27-
.github/
28-
.git/
29-
cmake_modules/
30-
.cmake/
31-
.clang-format
32-
.clang-tidy
33-
.pre-commit-config.yaml
34-
CMakeUserPresets.json
35-
test/resources/
36-
cmake-format.py
21+
build/**
22+
dist/**
23+
.git/**
24+
test/resources/**
3725
*.avro
3826
*.json
3927
*.parquet
28+
src/iceberg/util/murmurhash3_internal.*

dev/release/release_rc.sh

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,8 @@ cd "${SOURCE_TOP_DIR}"
4949

5050
if [ "${RELEASE_PULL}" -gt 0 ] || [ "${RELEASE_PUSH_TAG}" -gt 0 ]; then
5151
git_origin_url="$(git remote get-url origin)"
52-
if [ "${git_origin_url}" != "[email protected]:HeartLinked/iceberg-cpp.git" ]; then
53-
echo "This script must be ran with working copy of HeartLinked/iceberg-cpp."
54-
# if [ "${git_origin_url}" != "[email protected]:apache/iceberg-cpp.git" ]; then
55-
# echo "This script must be ran with working copy of apache/iceberg-cpp."
52+
if [ "${git_origin_url}" != "[email protected]:apache/iceberg-cpp.git" ]; then
53+
echo "This script must be ran with working copy of apache/iceberg-cpp."
5654
echo "The origin's URL: ${git_origin_url}"
5755
exit 1
5856
fi
@@ -96,7 +94,6 @@ if [ "${RELEASE_SIGN}" -gt 0 ]; then
9694
echo "Found GitHub Actions workflow with ID: ${run_id}"
9795
gh run watch --repo "${repository}" --exit-status "${run_id}"
9896

99-
# Create release candidate directory structure
10097
mkdir -p "${id}"
10198

10299
echo "Downloading .tar.gz from GitHub Releases"

dev/release/verify_rc.sh

Lines changed: 5 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -113,49 +113,6 @@ ensure_source_directory() {
113113
tar xf "${ARCHIVE_BASE_NAME}".tar.gz
114114
}
115115

116-
check_compiler() {
117-
echo "--- Verifying Build Environment ---"
118-
119-
# Check for minimum CMake version (e.g., 3.25)
120-
MIN_CMAKE_VERSION="3.25"
121-
CMAKE_VERSION=$(cmake --version | head -n1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
122-
echo "Found CMake version: $CMAKE_VERSION"
123-
if [ "$(printf '%s\n' "${MIN_CMAKE_VERSION}" "${CMAKE_VERSION}" | sort -V | head -n1)" != "${MIN_CMAKE_VERSION}" ]; then
124-
echo "ERROR: CMake ${MIN_CMAKE_VERSION} or higher is required, but found ${CMAKE_VERSION}."
125-
exit 1
126-
fi
127-
128-
# Check for C++23 compliant compiler
129-
local compiler_ok=0
130-
if command -v g++ >/dev/null 2>&1; then
131-
# Get major version: g++ (Debian 13.2.0-4) 13.2.0 -> 13
132-
GCC_MAJOR_VERSION=$(g++ -dumpversion | cut -d. -f1)
133-
echo "Found GCC version: $(g++ --version | head -n1)"
134-
# GCC 13 is the first version with full C++23 support
135-
if [ "${GCC_MAJOR_VERSION}" -ge 13 ]; then
136-
echo "GCC version is sufficient for C++23."
137-
compiler_ok=1
138-
fi
139-
fi
140-
141-
if [ "${compiler_ok}" -eq 0 ] && command -v clang++ >/dev/null 2>&1; then
142-
CLANG_MAJOR_VERSION=$(clang++ --version | head -n1 | grep -oE '[0-9]+' | head -n1)
143-
echo "Found Clang version: $(clang++ --version | head -n1)"
144-
# Clang 16 is the first version with full C++23 support
145-
if [ "${CLANG_MAJOR_VERSION}" -ge 16 ]; then
146-
echo "Clang version is sufficient for C++23."
147-
compiler_ok=1
148-
fi
149-
fi
150-
151-
if [ "${compiler_ok}" -eq 0 ]; then
152-
echo "ERROR: No C++23 compliant compiler found (GCC 13+ or Clang 16+ required)."
153-
exit 1
154-
fi
155-
156-
echo "--- Environment check passed ---"
157-
}
158-
159116
test_source_distribution() {
160117
echo "Building and testing Apache Iceberg C++..."
161118

@@ -171,7 +128,11 @@ test_source_distribution() {
171128
# Run tests
172129
ctest --test-dir build --output-on-failure --parallel $(nproc || sysctl -n hw.ncpu || echo 4)
173130

174-
echo "Build and test completed successfully!"
131+
# Install
132+
mkdir -p ./install_test
133+
cmake --install build --prefix ./install_test
134+
135+
echo "Build, test and install completed successfully!"
175136
}
176137

177138
setup_tmpdir "iceberg-cpp-${VERSION}-${RC}"
@@ -181,7 +142,6 @@ cd "${VERIFY_TMPDIR}"
181142
import_gpg_keys
182143
fetch_archive
183144
ensure_source_directory
184-
check_compiler
185145
pushd "${ARCHIVE_BASE_NAME}"
186146
test_source_distribution
187147
popd

0 commit comments

Comments
 (0)