Skip to content

Commit 57418d4

Browse files
authored
chore: add release script and github workflow (#193)
This contribution introduces release automation tooling including: - `/dev/release/README.md`: Release process documentation - `/dev/release/*.sh`: Release script utilities - `/dev/release/check_rat_report.py`: Check Apache lisence script for release - `/dev/release/rat_exclude_files.txt`: List of files excluded from RAT license checks - `.github/workflows/rc.yml`: GitHub Actions automation for release
1 parent 78d06bf commit 57418d4

File tree

10 files changed

+860
-25
lines changed

10 files changed

+860
-25
lines changed

.github/workflows/rc.yml

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
name: RC
19+
on:
20+
push:
21+
tags:
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
29+
30+
jobs:
31+
archive:
32+
name: Archive
33+
runs-on: ubuntu-latest
34+
timeout-minutes: 5
35+
steps:
36+
- name: Checkout
37+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
38+
39+
- name: Prepare for tag
40+
if: github.ref_type == 'tag'
41+
run: |
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}"
49+
50+
- name: Archive
51+
run: |
52+
ARCHIVE_FILE_NAME="apache-iceberg-cpp-${VERSION}-rc${RC}"
53+
tar_gz="${ARCHIVE_FILE_NAME}.tar.gz"
54+
echo "TAR_GZ=${tar_gz}" >> ${GITHUB_ENV}
55+
git archive HEAD --prefix "${ARCHIVE_FILE_NAME}/" --output "${tar_gz}"
56+
sha512sum "${tar_gz}" > "${tar_gz}.sha512"
57+
58+
- name: Audit
59+
run: |
60+
dev/release/run_rat.sh "${TAR_GZ}"
61+
62+
- uses: actions/upload-artifact@v4
63+
with:
64+
name: archive
65+
path: |
66+
apache-iceberg-cpp-*
67+
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-15
78+
- ubuntu-24.04
79+
# - windows-latest
80+
steps:
81+
- name: Checkout
82+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
83+
84+
- uses: actions/download-artifact@v4
85+
with:
86+
name: archive
87+
88+
- name: Verify
89+
run: |
90+
tar_gz=$(echo apache-iceberg-cpp-*.tar.gz)
91+
version=${tar_gz#apache-iceberg-cpp-}
92+
version=${version%.tar.gz}
93+
version=${version%%-rc*}
94+
if [ "${GITHUB_REF_TYPE}" = "tag" ]; then
95+
rc=${GITHUB_REF_NAME##*-rc}
96+
else
97+
rc=100
98+
fi
99+
echo "VERSION=${version}"
100+
echo "RC=${rc}"
101+
# The verify_rc.sh script will untar and
102+
# run cmake, build, tests (ctest) and install
103+
VERIFY_SIGN=0 VERIFY_DOWNLOAD=0 dev/release/verify_rc.sh "${version}" "${rc}"
104+
env:
105+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
106+
107+
upload:
108+
name: Upload
109+
if: github.ref_type == 'tag'
110+
needs:
111+
- verify
112+
runs-on: ubuntu-latest
113+
permissions:
114+
contents: write
115+
steps:
116+
- name: Checkout
117+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
118+
119+
- uses: actions/download-artifact@v4
120+
with:
121+
name: archive
122+
123+
- name: Upload
124+
run: |
125+
gh release create ${GITHUB_REF_NAME} \
126+
--prerelease \
127+
--title "Apache Iceberg C++ ${GITHUB_REF_NAME}" \
128+
--generate-notes \
129+
--verify-tag \
130+
apache-iceberg-cpp-*.tar.gz \
131+
apache-iceberg-cpp-*.tar.gz.sha*
132+
env:
133+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

dev/release/README.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
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.
18+
-->
19+
20+
# Release
21+
22+
## Overview
23+
24+
1. Test the revision to be released
25+
2. Prepare RC and vote (detailed later)
26+
3. Publish (detailed later)
27+
28+
### Prepare RC and vote
29+
30+
Run `dev/release/release_rc.sh` on a working copy of
31+
`[email protected]:apache/iceberg-cpp` not from your fork:
32+
33+
```console
34+
$ git clone [email protected]:apache/iceberg-cpp.git && cd iceberg-cpp
35+
$ dev/release/release_rc.sh ${VERSION} ${RC}
36+
(Send a vote email to [email protected].
37+
You can use a draft shown by release_rc.sh for the email.)
38+
```
39+
40+
Here is an example to release RC0 of version 0.1.0:
41+
42+
```console
43+
$ GH_TOKEN=${YOUR_GITHUB_TOKEN} dev/release/release_rc.sh 0.1.0 0
44+
```
45+
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.
47+
48+
Requirements to run `release_rc.sh`:
49+
50+
* You must be an Apache Iceberg committer or PMC member
51+
* You must prepare your PGP key for signing
52+
53+
If you don't have a PGP key, https://infra.apache.org/release-signing.html#generate
54+
may be helpful.
55+
56+
Your PGP key must be published in the KEYS file, which is hosted at:
57+
58+
* https://downloads.apache.org/iceberg/KEYS
59+
60+
See the header comment of them for how to add a PGP key.
61+
62+
If you are a first-time release manager, you need to add your public key to this file. To prevent formatting errors, please use the following commands instead of editing the file manually:
63+
64+
+ Check out the release distribution directory:
65+
66+
```console
67+
$ svn co https://dist.apache.org/repos/dist/release/iceberg
68+
$ cd iceberg
69+
```
70+
+ Append your GPG public key to the KEYS file. Replace <YOUR_KEY_ID> with your actual GPG key ID.
71+
72+
```console
73+
$ echo "" >> KEYS # append a newline
74+
$ gpg --list-sigs <YOUR_KEY_ID> >> KEYS # append signatures
75+
$ gpg --armor --export <YOUR_KEY_ID> >> KEYS # append public key block
76+
$ svn commit -m "Add GPG key for <YOUR_NAME>"
77+
```
78+
79+
### Publish
80+
81+
We need to publish to apache.org to publish a new release.
82+
83+
Run `dev/release/release.sh` to publish to apache.org:
84+
85+
```console
86+
$ GH_TOKEN=${YOUR_GITHUB_TOKEN} dev/release/release.sh ${VERSION} ${RC}
87+
```
88+
89+
Add the release to ASF's report database via [Apache Committee Report Helper](https://reporter.apache.org/addrelease.html?iceberg)
90+
91+
### Verify
92+
93+
We have a script for verifying a RC.
94+
95+
You must install the following to run the script:
96+
97+
* `curl`
98+
* `gpg`
99+
* `shasum` or `sha512sum`
100+
* `tar`
101+
* `cmake` (3.25 or higher)
102+
* C++23 compliant compiler (GCC 13+ or Clang 16+)
103+
104+
To verify a RC, run the following:
105+
106+
```console
107+
$ dev/release/verify_rc.sh ${VERSION} ${RC}
108+
```
109+
110+
If the verification is successful, the message `RC looks good!` is shown.

dev/release/check_rat_report.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Licensed to the Apache Software Foundation (ASF) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The ASF licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
20+
import fnmatch
21+
import re
22+
import sys
23+
import xml.etree.ElementTree as ET
24+
25+
if len(sys.argv) != 3:
26+
sys.stderr.write("Usage: %s exclude_globs.lst rat_report.xml\n" %
27+
sys.argv[0])
28+
sys.exit(1)
29+
30+
exclude_globs_filename = sys.argv[1]
31+
xml_filename = sys.argv[2]
32+
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)
40+
41+
tree = ET.parse(xml_filename)
42+
root = tree.getroot()
43+
resources = root.findall('resource')
44+
45+
all_ok = True
46+
for r in resources:
47+
approvals = r.findall('license-approval')
48+
if not approvals or approvals[0].attrib['name'] == 'true':
49+
continue
50+
clean_name = re.sub('^[^/]+/', '', r.attrib['name'])
51+
excluded = False
52+
for g in globs:
53+
if fnmatch.fnmatch(clean_name, g):
54+
excluded = True
55+
break
56+
if not excluded:
57+
sys.stdout.write("NOT APPROVED: %s (%s): %s\n" % (
58+
clean_name, r.attrib['name'], approvals[0].attrib['name']))
59+
all_ok = False
60+
61+
if not all_ok:
62+
sys.exit(1)
63+
64+
print('OK')
65+
sys.exit(0)

dev/release/rat_exclude_files.txt

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

0 commit comments

Comments
 (0)