This is an automated email from the ASF dual-hosted git repository.
raulcd pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-swift.git
The following commit(s) were added to refs/heads/main by this push:
new 5adbb48 chore: Add release scripts (#42)
5adbb48 is described below
commit 5adbb488ddc48c83ab890de8c0b011d49d6abbb5
Author: Sutou Kouhei <[email protected]>
AuthorDate: Fri Jun 20 18:27:46 2025 +0900
chore: Add release scripts (#42)
## What's Changed
This is based on the release scripts in apache/arrow-js.
Here is the release workflow:
1. Run `dev/release/release_rc.sh 21.0.0 0`
1. This push `v21.0.0-rc0` tag
2. The tag push runs GitHub Actions workflow for RC that:
1. Generates source archive
2. Verifies these artifacts
3. Creates a GitHub Release for the RC and uploads these artifacts to
the GitHub Release
3. This downloads these artifacts from the GitHub Release
4. This signs these artifacts on local and upload these signs to the
GitHub Release
5. This shows vote e-mail template
2. Start a vote on `[email protected]`
3. Run `dev/release/release.sh 21.0.0 0` after the vote carried
1. This push `v21.0.0`tag
2. The tag push runs GitHub Actions workflow for release that:
1. Creates a GitHub Release for the release and copies all artifacts
from the GitHub Release for the RC
3. This uploads the voted source archive to
https://dist.apache.org/repos/dist/release/arrow/
4. This removes old releases from
https://dist.apache.org/repos/dist/release/arrow/
4. Add the release to ASF's report database:
https://reporter.apache.org/addrelease.html?arrow
See also the added `dev/release/README.md`.
Closes #8.
---
.github/workflows/rc.yaml | 159 +++++++++++++++++++++++++
.github/workflows/release.yaml | 58 +++++++++
.gitignore | 4 +
ci/scripts/build.sh | 12 +-
.gitignore => dev/release/.env.example | 30 ++---
dev/release/README.md | 212 +++++++++++++++++++++++++++++++++
dev/release/release.sh | 115 ++++++++++++++++++
dev/release/release_rc.sh | 176 +++++++++++++++++++++++++++
dev/release/verify_rc.sh | 159 +++++++++++++++++++++++++
9 files changed, 906 insertions(+), 19 deletions(-)
diff --git a/.github/workflows/rc.yaml b/.github/workflows/rc.yaml
new file mode 100644
index 0000000..9702de8
--- /dev/null
+++ b/.github/workflows/rc.yaml
@@ -0,0 +1,159 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: RC
+
+on:
+ push:
+ branches:
+ - "**"
+ - "!dependabot/**"
+ tags:
+ - "*-rc*"
+ pull_request:
+
+concurrency:
+ group: ${{ github.repository }}-${{ github.head_ref || github.sha }}-${{
github.workflow }}
+ cancel-in-progress: true
+
+permissions:
+ contents: read
+
+jobs:
+ target:
+ name: Target
+ runs-on: ubuntu-latest
+ timeout-minutes: 5
+ outputs:
+ version: ${{ steps.detect.outputs.version }}
+ rc: ${{ steps.detect.outputs.rc }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #
v4.2.2
+ - name: Detect
+ id: detect
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ if [ "${GITHUB_REF_TYPE}" = "tag" ]; then
+ version=${GITHUB_REF_NAME%-rc*}
+ version=${version#v}
+ rc=${GITHUB_REF_NAME#*-rc}
+ else
+ last_release_tag=$(gh release list \
+ --exclude-drafts \
+ --exclude-pre-releases \
+ --jq '.[].tagName' \
+ --json tagName \
+ --limit 1)
+ if [ -n "${last_release_tag}" ]; then
+ version=${last_release_tag#v}
+ else
+ version=1.0.0
+ fi
+ rc=$(date +%Y%m%d)
+ fi
+ echo "version=${version}" >> ${GITHUB_OUTPUT}
+ echo "rc=${rc}" >> ${GITHUB_OUTPUT}
+
+ source:
+ name: Source
+ needs: target
+ runs-on: ubuntu-latest
+ timeout-minutes: 5
+ env:
+ RC: ${{ needs.target.outputs.rc }}
+ VERSION: ${{ needs.target.outputs.version }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #
v4.2.2
+ - name: Archive
+ run: |
+ id="apache-arrow-swift-${VERSION}"
+ tar_gz="${id}.tar.gz"
+ echo "TAR_GZ=${tar_gz}" >> ${GITHUB_ENV}
+ git archive HEAD --prefix "${id}/" --output "${tar_gz}"
+ sha256sum "${tar_gz}" > "${tar_gz}.sha256"
+ sha512sum "${tar_gz}" > "${tar_gz}.sha512"
+ - name: Upload
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
# v4.6.2
+ with:
+ name: release-source
+ path: |
+ apache-arrow-swift-*.tar.gz*
+ - name: Audit
+ run: |
+ dev/release/run_rat.sh "${TAR_GZ}"
+
+ verify:
+ name: Verify
+ needs:
+ - source
+ - target
+ runs-on: ubuntu-latest
+ timeout-minutes: 45
+ env:
+ RC: ${{ needs.target.outputs.rc }}
+ VERSION: ${{ needs.target.outputs.version }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #
v4.2.2
+ - name: Setup Swift
+ uses:
swift-actions/setup-swift@682457186b71c25a884c45c06f859febbe259240 # v2.3.0
+ with:
+ swift-version: "5.10"
+ - name: Download
+ uses:
actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
+ with:
+ pattern: release-*
+ - name: Verify
+ env:
+ VERIFY_DEFAULT: 0
+ VERIFY_SOURCE: 1
+ run: |
+ mv release-*/* ./
+ dev/release/verify_rc.sh "${VERSION}" "${RC}"
+
+ upload:
+ name: Upload
+ needs:
+ - target
+ - verify
+ runs-on: ubuntu-latest
+ timeout-minutes: 5
+ permissions:
+ contents: write
+ env:
+ RC: ${{ needs.target.outputs.rc }}
+ VERSION: ${{ needs.target.outputs.version }}
+ steps:
+ - name: Download
+ uses:
actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
+ with:
+ pattern: release-*
+ - name: Upload
+ if: github.ref_type == 'tag'
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ gh release create ${GITHUB_REF_NAME} \
+ --generate-notes \
+ --prerelease \
+ --repo ${GITHUB_REPOSITORY} \
+ --title "Apache Arrow Swift ${VERSION} RC${RC}" \
+ --verify-tag \
+ release-*/*.tar.gz*
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
new file mode 100644
index 0000000..8aa89c9
--- /dev/null
+++ b/.github/workflows/release.yaml
@@ -0,0 +1,58 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: Release
+
+on:
+ push:
+ tags:
+ - "*"
+ - "!*-rc*"
+
+permissions:
+ contents: write
+
+env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+jobs:
+ publish:
+ name: Publish
+ runs-on: ubuntu-latest
+ timeout-minutes: 5
+ steps:
+ - name: Download RC contents
+ run: |
+ set -x
+ latest_rc_tag=$(gh release list \
+ --jq '.[].tagName' \
+ --json tagName \
+ --repo ${GITHUB_REPOSITORY} | \
+ grep -F "${GITHUB_REF_NAME}-rc" | \
+ head -n1)
+ gh release download ${latest_rc_tag} \
+ --repo ${GITHUB_REPOSITORY} \
+ --dir dists
+ - name: Create GitHub Release
+ run: |
+ version=${GITHUB_REF_NAME#v}
+ gh release create ${GITHUB_REF_NAME} \
+ --generate-notes \
+ --repo ${GITHUB_REPOSITORY} \
+ --title "Apache Arrow Swift ${version}" \
+ --verify-tag \
+ dists/*
diff --git a/.gitignore b/.gitignore
index 6c315b8..65bfb48 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,7 @@ xcuserdata/
/dev/release/apache-rat-*.jar
/dev/release/filtered_rat.txt
/dev/release/rat.xml
+
+# Release
+/apache-arrow-swift-*.tar.gz*
+/dev/release/.env
diff --git a/ci/scripts/build.sh b/ci/scripts/build.sh
index 7acb359..043642d 100755
--- a/ci/scripts/build.sh
+++ b/ci/scripts/build.sh
@@ -37,14 +37,18 @@ rm -rf "${build_dir}"
mkdir -p "${build_dir}"
cp -a "${source_dir}" "${build_dir}/source"
rm -rf "${build_dir}/source/.build"
-mkdir -p /cache/swift-build
-ln -s /cache/swift-build "${build_dir}/source/.build"
+if [ -d /cache ]; then
+ mkdir -p /cache/swift-build
+ ln -s /cache/swift-build "${build_dir}/source/.build"
+fi
github_actions_group_end
github_actions_group_begin "Generate data"
data_gen_dir="${build_dir}/source/data-generator/swift-datagen"
-export GOCACHE="/cache/go-build"
-export GOMODCACHE="/cache/go-mod"
+if [ -d /cache ]; then
+ export GOCACHE="/cache/go-build"
+ export GOMODCACHE="/cache/go-mod"
+fi
export GOPATH="${build_dir}"
pushd "${data_gen_dir}"
go get -d ./...
diff --git a/.gitignore b/dev/release/.env.example
similarity index 62%
copy from .gitignore
copy to dev/release/.env.example
index 6c315b8..c926902 100644
--- a/.gitignore
+++ b/dev/release/.env.example
@@ -15,19 +15,19 @@
# specific language governing permissions and limitations
# under the License.
-*.xcodeproj
-.DS_Store
-.build/
-.netrc
-.swiftpm/
-DerivedData/
-Packages/
-xcuserdata/
-
-# Docker
-/.docker/
+# The GitHub token to upload artifacts to GitHub Release.
+#
+# You must set this.
+#GH_TOKEN=secret
+export GH_TOKEN
-# Release Audit Tool
-/dev/release/apache-rat-*.jar
-/dev/release/filtered_rat.txt
-/dev/release/rat.xml
+# The GPG key ID to sign artifacts. The GPG key ID must be registered
+# to both of the followings:
+#
+# * https://dist.apache.org/repos/dist/dev/arrow/KEYS
+# * https://dist.apache.org/repos/dist/release/arrow/KEYS
+#
+# See these files how to import your GPG key ID to these files.
+#
+# You must set this.
+#GPG_KEY_ID=08D3564B7C6A9CAFBFF6A66791D18FCF079F8007
diff --git a/dev/release/README.md b/dev/release/README.md
new file mode 100644
index 0000000..59461b6
--- /dev/null
+++ b/dev/release/README.md
@@ -0,0 +1,212 @@
+<!---
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+# Release
+
+## Overview
+
+1. Test the revision to be released
+2. Prepare RC and vote (detailed later)
+3. Publish (detailed later)
+4. Announce the new release on the mailing list (detailed later)
+5. Announce the new release on social media (detailed later)
+
+## Prepare release environment
+
+This step is needed only when you act as a release manager the first time.
+
+We use the following variables in multiple steps:
+
+* `GH_TOKEN`: GitHub personal access token to automate GitHub related
+ operations
+* `GPG_KEY_ID`: PGP key ID that is used for signing official artifacts
+ by GnuPG
+
+We use `dev/release/.env` to share these variables in multiple
+steps. You can use `dev/release/.env.example` as a template:
+
+```console
+$ cp dev/release/.env{.example,}
+$ chmod go-r dev/release/.env
+$ editor dev/release/.env
+```
+
+See
+https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
+how to prepare GitHub personal access token for `GH_TOKEN`.
+
+Note that you also need to install `gh` command because our scripts
+use `gh` command to use GitHub API. See
+https://github.com/cli/cli#installation how to install `gh`
+command.
+
+If you don't have a PGP key for `GPG_KEY_ID`, see
+https://infra.apache.org/release-signing.html#genegrate how to
+generate your PGP key.
+
+Your PGP key must be registered to the followings:
+
+ * https://dist.apache.org/repos/dist/dev/arrow/KEYS
+ * https://dist.apache.org/repos/dist/release/arrow/KEYS
+
+See the header comment of them how to add a PGP key.
+
+Apache arrow committers can update them by Subversion client with
+their ASF account. e.g.:
+
+```console
+$ svn co https://dist.apache.org/repos/dist/dev/arrow
+$ cd arrow
+$ head KEYS
+(This shows how to update KEYS)
+$ svn ci KEYS
+```
+
+## Prepare RC and vote
+
+You can use `dev/release/release_rc.sh`.
+
+Requirements to run `release_rc.sh`:
+
+* You must be an Apache Arrow committer or PMC member
+* You must prepare your PGP key for signing
+
+Run `dev/release/release_rc.sh` on a working copy of
+`[email protected]:apache/arrow-swift` not your fork:
+
+```console
+$ git clone [email protected]:apache/arrow-swift.git
+$ cd arrow-swift
+$ dev/release/release_rc.sh ${VERSION} ${RC}
+(Send a vote email to [email protected].
+ You can use a draft shown by release_rc.sh for the email.)
+```
+
+Here is an example to release 21.0.0 RC0:
+
+```console
+$ dev/release/release_rc.sh 21.0.0 0
+```
+
+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.
+
+## Publish
+
+We need to do the followings to publish a new release:
+
+* Publish the source archive to apache.org
+
+Run `dev/release/release.sh` on a working copy of
+`[email protected]:apache/arrow-swift` not your fork to publish the
+source archive to apache.org:
+
+```console
+$ dev/release/release.sh ${VERSION} ${RC}
+```
+
+Here is an example to release 21.0.0 RC0:
+
+```console
+$ dev/release/release.sh 21.0.0 0
+```
+
+Add the release to ASF's report database via [Apache Committee Report
+Helper](https://reporter.apache.org/addrelease.html?arrow).
+
+## Announce the new release on the mailing list
+
+Send an email to "[email protected]" from your Apache email, CC'ing
[email protected]/[email protected]. See an [example
+post](https://lists.apache.org/thread/bxpt0r8kw0ltgywnylqdroskkt6966z4).
+
+```
+To: [email protected]
+CC: [email protected], [email protected]
+Subject: [ANNOUNCE] Apache Arrow Swift 21.0.0 released
+
+The Apache Arrow community is pleased to announce the Arrow Swift 21.0.0
+release.
+
+The release is available now.
+
+Source archive:
+ https://www.apache.org/dyn/closer.lua/arrow/apache-arrow-swift-21.0.0/
+
+On Swift Package Index:
+ https://swiftpackageindex.com/apache/arrow
+
+Read the full changelog:
+ https://github.com/apache/arrow-swift/releases/tag/v21.0.0
+
+What is Apache Arrow?
+---------------------
+
+Apache Arrow is a universal columnar format and multi-language toolbox
+for fast data interchange and in-memory analytics. It houses a set of
+canonical in-memory representations of flat and hierarchical data
+along with multiple language-bindings for structure manipulation. It
+also provides low-overhead streaming and batch messaging, zero-copy
+interprocess communication (IPC), and vectorized in-memory analytics
+libraries.
+
+Please report any feedback to the GitHub repository:
+ https://github.com/apache/arrow-swift/issues
+ https://github.com/apache/arrow-swift/discussions
+
+Regards,
+The Apache Arrow community.
+```
+
+## Announce the new release on social media
+
+Make a post on our [BlueSky](https://bsky.app/profile/arrow.apache.org) and
+[LinkedIn](https://www.linkedin.com/company/apache-arrow/) accounts. (Ask
+your fellow PMC members for access if need be, or ask a PMC member to make the
+post on your behalf.) The post should link to the blog post. See [example
+BlueSky post](https://bsky.app/profile/arrow.apache.org/post/3lioi6ov5h22d)
+and [example LinkedIn
post](https://www.linkedin.com/posts/apache-arrow_apache-arrow-java-1820-release-activity-7298633716522758144-L71x).
+
+## Verify
+
+We have a script to verify a RC.
+
+You must install the following commands to use the script:
+
+* `curl`
+* `go`
+* `gpg`
+* `shasum` or `sha256sum`/`sha512sum`
+* `swift` 5.10 (6.0 or later don't work)
+* `tar`
+
+To verify a RC, run the following command line:
+
+```console
+$ dev/release/verify_rc.sh ${VERSION} ${RC}
+```
+
+Here is an example to verify the release 21.0.0 RC0:
+
+```console
+$ dev/release/verify_rc.sh 21.0.0 0
+```
+
+If the verification is successful, the message `RC looks good!` is shown.
diff --git a/dev/release/release.sh b/dev/release/release.sh
new file mode 100755
index 0000000..5a0832f
--- /dev/null
+++ b/dev/release/release.sh
@@ -0,0 +1,115 @@
+#!/usr/bin/env bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+set -eu
+
+SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+SOURCE_TOP_DIR="$(cd "${SOURCE_DIR}/../../" && pwd)"
+
+if [ "$#" -ne 2 ]; then
+ echo "Usage: $0 <version> <rc>"
+ echo " e.g.: $0 21.0.0 0"
+ exit 1
+fi
+
+version="$1"
+rc="$2"
+
+: "${RELEASE_DEFAULT:=1}"
+: "${RELEASE_TAG:=${RELEASE_DEFAULT}}"
+: "${RELEASE_UPLOAD:=${RELEASE_DEFAULT}}"
+: "${RELEASE_CLEAN:=${RELEASE_DEFAULT}}"
+
+if [ ! -f "${SOURCE_DIR}/.env" ]; then
+ echo "You must create ${SOURCE_DIR}/.env"
+ echo "You can use ${SOURCE_DIR}/.env.example as template"
+ exit 1
+fi
+. "${SOURCE_DIR}/.env"
+
+cd "${SOURCE_TOP_DIR}"
+
+git_origin_url="$(git remote get-url origin)"
+repository="${git_origin_url#*github.com?}"
+repository="${repository%.git}"
+case "${git_origin_url}" in
[email protected]:apache/arrow-swift.git |
https://github.com/apache/arrow-swift.git)
+ : # OK
+ ;;
+*)
+ echo "This script must be ran with working copy of apache/arrow-swift."
+ echo "The origin's URL: ${git_origin_url}"
+ exit 1
+ ;;
+esac
+
+tag="v${version}"
+rc_tag="${tag}-rc${rc}"
+if [ "${RELEASE_TAG}" -gt 0 ]; then
+ echo "Tagging for release: ${tag}"
+ git tag -a -m "${version}" "${tag}" "${rc_tag}^{}"
+ git push origin "${tag}"
+fi
+
+release_id="apache-arrow-swift-${version}"
+source_archive="apache-arrow-swift-${version}.tar.gz"
+dist_url="https://dist.apache.org/repos/dist/release/arrow"
+dist_base_dir="dev/release/dist"
+dist_dir="${dist_base_dir}/${release_id}"
+if [ "${RELEASE_UPLOAD}" -gt 0 ]; then
+ echo "Checking out ${dist_url}"
+ rm -rf "${dist_base_dir}"
+ svn co --depth=empty "${dist_url}" "${dist_base_dir}"
+ gh release download "${rc_tag}" \
+ --dir "${dist_dir}" \
+ --pattern "${source_archive}*" \
+ --repo "${repository}" \
+ --skip-existing
+
+ echo "Uploading to release/"
+ pushd "${dist_base_dir}"
+ svn add "${release_id}"
+ svn ci -m "Apache Arrow Swift ${version}"
+ popd
+ rm -rf "${dist_base_dir}"
+fi
+
+if [ "${RELEASE_CLEAN}" -gt 0 ]; then
+ echo "Keep only the latest versions"
+ old_releases=$(
+ svn ls https://dist.apache.org/repos/dist/release/arrow/ |
+ grep -E '^apache-arrow-swift-' |
+ sort --version-sort --reverse |
+ tail -n +2
+ )
+ for old_release_version in ${old_releases}; do
+ echo "Remove old release ${old_release_version}"
+ svn \
+ delete \
+ -m "Remove old Apache Arrow Swift release: ${old_release_version}" \
+ "https://dist.apache.org/repos/dist/release/arrow/${old_release_version}"
+ done
+fi
+
+echo "Success! The release is available here:"
+echo " https://dist.apache.org/repos/dist/release/arrow/${release_id}"
+echo " https://swiftpackageindex.com/apache/arrow"
+echo
+echo "Add this release to ASF's report database:"
+echo " https://reporter.apache.org/addrelease.html?arrow"
diff --git a/dev/release/release_rc.sh b/dev/release/release_rc.sh
new file mode 100755
index 0000000..ff5e5f0
--- /dev/null
+++ b/dev/release/release_rc.sh
@@ -0,0 +1,176 @@
+#!/usr/bin/env bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+set -eu
+
+SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+SOURCE_TOP_DIR="$(cd "${SOURCE_DIR}/../../" && pwd)"
+
+if [ "$#" -ne 2 ]; then
+ echo "Usage: $0 <version> <rc>"
+ echo " e.g.: $0 21.0.0 0"
+ exit 1
+fi
+
+version="$1"
+rc="$2"
+
+: "${RELEASE_DEFAULT:=1}"
+: "${RELEASE_PULL:=${RELEASE_DEFAULT}}"
+: "${RELEASE_PUSH_TAG:=${RELEASE_DEFAULT}}"
+: "${RELEASE_SIGN:=${RELEASE_DEFAULT}}"
+: "${RELEASE_UPLOAD:=${RELEASE_DEFAULT}}"
+
+if [ ! -f "${SOURCE_DIR}/.env" ]; then
+ echo "You must create ${SOURCE_DIR}/.env"
+ echo "You can use ${SOURCE_DIR}/.env.example as template"
+ exit 1
+fi
+. "${SOURCE_DIR}/.env"
+
+cd "${SOURCE_TOP_DIR}"
+
+if [ "${RELEASE_PULL}" -gt 0 ] || [ "${RELEASE_PUSH_TAG}" -gt 0 ]; then
+ git_origin_url="$(git remote get-url origin)"
+ case "${git_origin_url}" in
+ [email protected]:apache/arrow-swift.git |
https://github.com/apache/arrow-swift.git)
+ : # OK
+ ;;
+ *)
+ echo "This script must be ran with working copy of apache/arrow-swift."
+ echo "The origin's URL: ${git_origin_url}"
+ exit 1
+ ;;
+ esac
+fi
+
+if [ "${RELEASE_PULL}" -gt 0 ]; then
+ echo "Ensure using the latest commit"
+ git checkout main
+ git pull --ff-only
+fi
+
+rc_tag="v${version}-rc${rc}"
+if [ "${RELEASE_PUSH_TAG}" -gt 0 ]; then
+ echo "Tagging for RC: ${rc_tag}"
+ git tag -a -m "${version} RC${rc}" "${rc_tag}"
+ git push origin "${rc_tag}"
+fi
+
+rc_hash="$(git rev-list --max-count=1 "${rc_tag}")"
+
+artifacts_dir="apache-arrow-swift-${version}-rc${rc}"
+signed_artifacts_dir="${artifacts_dir}-signed"
+
+if [ "${RELEASE_SIGN}" -gt 0 ]; then
+ git_origin_url="$(git remote get-url origin)"
+ repository="${git_origin_url#*github.com?}"
+ repository="${repository%.git}"
+
+ echo "Looking for GitHub Actions workflow on ${repository}:${rc_tag}"
+ run_id=""
+ while true; do
+ sleep 10
+ echo "Waiting for run to start..."
+ run_id=$(gh run list \
+ --branch "${rc_tag}" \
+ --jq ".[].databaseId" \
+ --json 'databaseId' \
+ --limit 1 \
+ --repo "${repository}" \
+ --workflow rc.yaml)
+ if [ -n "${run_id}" ]; then
+ break
+ fi
+ sleep 300
+ done
+
+ echo "Found GitHub Actions workflow with ID: ${run_id}"
+ gh run watch \
+ --exit-status "${run_id}" \
+ --interval 300 \
+ --repo "${repository}"
+
+ echo "Downloading artifacts from GitHub Releases"
+ gh release download "${rc_tag}" \
+ --dir "${artifacts_dir}" \
+ --repo "${repository}" \
+ --skip-existing
+
+ echo "Signing artifacts"
+ rm -rf "${signed_artifacts_dir}"
+ mkdir -p "${signed_artifacts_dir}"
+ for artifact in "${artifacts_dir}"/*; do
+ case "${artifact}" in
+ *.asc | *.sha256 | *.sha512)
+ continue
+ ;;
+ esac
+ gpg \
+ --armor \
+ --detach-sig \
+ --local-user "${GPG_KEY_ID}" \
+ --output "${signed_artifacts_dir}/$(basename "${artifact}").asc" \
+ "${artifact}"
+ done
+ rm -rf "${artifacts_dir}"
+fi
+
+if [ "${RELEASE_UPLOAD}" -gt 0 ]; then
+ echo "Uploading signature"
+ gh release upload "${rc_tag}" \
+ --clobber \
+ --repo "${repository}" \
+ "${signed_artifacts_dir}"/*.asc
+fi
+
+rm -rf "${signed_artifacts_dir}"
+
+echo
+echo "Draft email for [email protected] mailing list"
+echo ""
+echo "---------------------------------------------------------"
+cat <<MAIL
+To: [email protected]
+Subject: [VOTE][Swift] Release Apache Arrow Swift ${version} RC${rc}
+
+Hi,
+
+I would like to propose the following release candidate (RC${rc}) of
+Apache Arrow Swift version ${version}.
+
+This release candidate is based on commit:
+${rc_hash} [1]
+
+The source release rc${rc} is hosted at [2].
+
+Please download, verify checksums and signatures, run the unit tests,
+and vote on the release. See [3] for how to validate a release candidate.
+
+The vote will be open for at least 72 hours.
+
+[ ] +1 Release this as Apache Arrow Swift ${version}
+[ ] +0
+[ ] -1 Do not release this as Apache Arrow Swift ${version} because...
+
+[1]: https://github.com/apache/arrow-swift/tree/${rc_hash}
+[2]: https://github.com/apache/arrow-swift/releases/${rc_tag}
+[3]:
https://github.com/apache/arrow-swift/blob/main/dev/release/README.md#verify
+MAIL
+echo "---------------------------------------------------------"
diff --git a/dev/release/verify_rc.sh b/dev/release/verify_rc.sh
new file mode 100755
index 0000000..4c73f70
--- /dev/null
+++ b/dev/release/verify_rc.sh
@@ -0,0 +1,159 @@
+#!/usr/bin/env bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+set -eu
+set -o pipefail
+
+SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+TOP_SOURCE_DIR="$(dirname "$(dirname "${SOURCE_DIR}")")"
+
+if [ "$#" -ne 2 ]; then
+ echo "Usage: $0 <version> <rc>"
+ echo " e.g.: $0 21.0.0 0"
+ exit 1
+fi
+
+github_actions_group_begin() {
+ echo "::group::$1"
+ set -x
+}
+
+github_actions_group_end() {
+ set +x
+ echo "::endgroup::"
+}
+
+github_actions_group_begin "Prepare"
+
+VERSION="$1"
+RC="$2"
+
+ARROW_DIST_BASE_URL="https://dist.apache.org/repos/dist/release/arrow"
+DOWNLOAD_RC_BASE_URL="https://github.com/apache/arrow-swift/releases/download/v${VERSION}-rc${RC}"
+ARCHIVE_BASE_NAME="apache-arrow-swift-${VERSION}"
+
+: "${VERIFY_DEFAULT:=1}"
+: "${VERIFY_DOWNLOAD:=${VERIFY_DEFAULT}}"
+: "${VERIFY_SIGN:=${VERIFY_DEFAULT}}"
+: "${VERIFY_SOURCE:=${VERIFY_DEFAULT}}"
+
+VERIFY_SUCCESS=no
+
+setup_tmpdir() {
+ cleanup() {
+ # Go removes the write permissions for user from downloaded files.
+ chmod -R u+w "${VERIFY_TMPDIR}" || :
+ if [ "${VERIFY_SUCCESS}" = "yes" ]; then
+ rm -rf "${VERIFY_TMPDIR}"
+ else
+ echo "::endgroup::"
+ echo "Failed to verify release candidate. See ${VERIFY_TMPDIR} for
details."
+ fi
+ }
+
+ if [ -z "${VERIFY_TMPDIR:-}" ]; then
+ VERIFY_TMPDIR="$(mktemp -d -t "$1.XXXXX")"
+ trap cleanup EXIT
+ else
+ mkdir -p "${VERIFY_TMPDIR}"
+ fi
+}
+
+download() {
+ curl \
+ --fail \
+ --location \
+ --remote-name \
+ --show-error \
+ --silent \
+ "$1"
+}
+
+download_rc_file() {
+ if [ "${VERIFY_DOWNLOAD}" -gt 0 ]; then
+ download "${DOWNLOAD_RC_BASE_URL}/$1"
+ else
+ cp "${TOP_SOURCE_DIR}/$1" "$1"
+ fi
+}
+
+import_gpg_keys() {
+ if [ "${VERIFY_SIGN}" -gt 0 ]; then
+ download "${ARROW_DIST_BASE_URL}/KEYS"
+ gpg --import KEYS
+ fi
+}
+
+if type shasum >/dev/null 2>&1; then
+ sha256_verify="shasum -a 256 -c"
+ sha512_verify="shasum -a 512 -c"
+else
+ sha256_verify="sha256sum -c"
+ sha512_verify="sha512sum -c"
+fi
+
+fetch_archive() {
+ download_rc_file "${ARCHIVE_BASE_NAME}.tar.gz"
+ if [ "${VERIFY_SIGN}" -gt 0 ]; then
+ download_rc_file "${ARCHIVE_BASE_NAME}.tar.gz.asc"
+ gpg --verify "${ARCHIVE_BASE_NAME}.tar.gz.asc"
"${ARCHIVE_BASE_NAME}.tar.gz"
+ fi
+ download_rc_file "${ARCHIVE_BASE_NAME}.tar.gz.sha256"
+ ${sha256_verify} "${ARCHIVE_BASE_NAME}.tar.gz.sha256"
+ download_rc_file "${ARCHIVE_BASE_NAME}.tar.gz.sha512"
+ ${sha512_verify} "${ARCHIVE_BASE_NAME}.tar.gz.sha512"
+}
+
+ensure_source_directory() {
+ tar xf "${ARCHIVE_BASE_NAME}".tar.gz
+}
+
+test_source_distribution() {
+ if [ "${VERIFY_SOURCE}" -le 0 ]; then
+ return 0
+ fi
+
+ "${TOP_SOURCE_DIR}/ci/scripts/build.sh" "$(pwd)" "$(pwd)/../build"
+ "${TOP_SOURCE_DIR}/ci/scripts/test.sh" "$(pwd)" "$(pwd)/../build"
+}
+
+github_actions_group_end
+
+github_actions_group_begin "Setup temporary directory"
+setup_tmpdir "arrow-swift-${VERSION}-${RC}"
+echo "Working in sandbox ${VERIFY_TMPDIR}"
+cd "${VERIFY_TMPDIR}"
+github_actions_group_end
+
+github_actions_group_begin "Prepare source directory"
+import_gpg_keys
+fetch_archive
+ensure_source_directory
+github_actions_group_end
+
+pushd "${ARCHIVE_BASE_NAME}"
+
+github_actions_group_begin "Test source distribution"
+test_source_distribution
+github_actions_group_end
+
+popd
+
+VERIFY_SUCCESS=yes
+echo "RC looks good!"