Skip to content

Commit f722749

Browse files
GH-3547: Add semi-automated release pipeline for Apache Parquet Java
Adds a release automation framework modeled after Apache Polaris, adapted for Parquet's Maven-based build. Replaces the manual maven-release-plugin workflow with explicit, scriptable steps that support both CI (GitHub Actions) and local execution, with dry-run by default. Scripts (release/bin/): - prepare-rc.sh: full pre-vote flow (branch, version, tag, Nexus, SVN, GitHub pre-release, vote email) - publish-release.sh: full post-vote flow (SVN promotion, final tag, Nexus release, GitHub release, version bump, announce email) - cancel-rc.sh: rollback a failed RC (Nexus drop, SVN cleanup) Shared libraries (release/libs/): - _constants.sh, _log.sh, _exec.sh, _version.sh - _github.sh, _nexus.sh, _maven.sh GitHub Actions workflows: - release-prepare-rc.yml, release-publish.yml, release-cancel-rc.yml - ci-release-scripts.yml (bats unit tests on PR/push) Includes 85 bats unit tests covering all shared libraries.
1 parent 32a484a commit f722749

22 files changed

Lines changed: 2864 additions & 0 deletions
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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+
name: Test Release Scripts
21+
22+
on:
23+
pull_request:
24+
paths:
25+
- 'release/**'
26+
push:
27+
branches:
28+
- master
29+
paths:
30+
- 'release/**'
31+
32+
jobs:
33+
bats:
34+
name: Release Script Unit Tests
35+
runs-on: ubuntu-latest
36+
37+
steps:
38+
- name: Checkout repository
39+
uses: actions/checkout@v4
40+
with:
41+
fetch-depth: 0
42+
43+
- name: Install bats-core
44+
run: |
45+
sudo apt-get update
46+
sudo apt-get install -y bats
47+
48+
- name: Run bats tests
49+
run: bats release/tests/*.bats
50+
51+
- name: Verify scripts are executable
52+
run: |
53+
for script in release/bin/*.sh; do
54+
if [[ ! -x "$script" ]]; then
55+
echo "ERROR: $script is not executable"
56+
exit 1
57+
fi
58+
done
59+
echo "All scripts are executable"
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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+
name: Release - Cancel RC
21+
22+
on:
23+
workflow_dispatch:
24+
inputs:
25+
version:
26+
description: 'Release version (e.g., 1.18.0)'
27+
required: true
28+
type: string
29+
rc_number:
30+
description: 'RC number to cancel (e.g., 0)'
31+
required: true
32+
type: string
33+
staging_repo_id:
34+
description: 'Nexus staging repository ID to drop (e.g., orgapacheparquet-1234)'
35+
required: true
36+
type: string
37+
dry_run:
38+
description: 'Dry run mode (no actual changes)'
39+
required: false
40+
type: boolean
41+
default: true
42+
43+
jobs:
44+
cancel-rc:
45+
name: Cancel Release Candidate
46+
runs-on: ubuntu-latest
47+
permissions:
48+
contents: read
49+
50+
steps:
51+
- name: Checkout repository
52+
uses: actions/checkout@v4
53+
with:
54+
fetch-depth: 0
55+
persist-credentials: false
56+
57+
- name: Install Subversion
58+
run: sudo apt-get update && sudo apt-get install -y subversion
59+
60+
- name: Cancel Release Candidate
61+
env:
62+
DRY_RUN: ${{ inputs.dry_run && '1' || '0' }}
63+
NEXUS_USERNAME: ${{ secrets.PARQUET_NEXUS_USER }}
64+
NEXUS_PASSWORD: ${{ secrets.PARQUET_NEXUS_PASSWORD }}
65+
SVN_USERNAME: ${{ secrets.PARQUET_SVN_DEV_USERNAME }}
66+
SVN_PASSWORD: ${{ secrets.PARQUET_SVN_DEV_PASSWORD }}
67+
INPUT_VERSION: ${{ inputs.version }}
68+
INPUT_RC_NUMBER: ${{ inputs.rc_number }}
69+
INPUT_STAGING_REPO_ID: ${{ inputs.staging_repo_id }}
70+
run: |
71+
./release/bin/cancel-rc.sh \
72+
"${INPUT_VERSION}" \
73+
"${INPUT_RC_NUMBER}" \
74+
"${INPUT_STAGING_REPO_ID}"
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
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+
name: Release - Prepare RC
21+
22+
on:
23+
workflow_dispatch:
24+
inputs:
25+
version:
26+
description: 'Release version (e.g., 1.18.0)'
27+
required: true
28+
type: string
29+
rc_number:
30+
description: 'RC number override (leave empty for auto-detect)'
31+
required: false
32+
type: string
33+
default: ''
34+
dry_run:
35+
description: 'Dry run mode (no actual changes)'
36+
required: false
37+
type: boolean
38+
default: true
39+
40+
jobs:
41+
prepare-rc:
42+
name: Prepare Release Candidate
43+
runs-on: ubuntu-latest
44+
permissions:
45+
contents: write
46+
47+
steps:
48+
- name: Checkout repository
49+
uses: actions/checkout@v4
50+
with:
51+
fetch-depth: 0
52+
token: ${{ secrets.GITHUB_TOKEN }}
53+
54+
- name: Set up JDK 11
55+
uses: actions/setup-java@v4
56+
with:
57+
distribution: temurin
58+
java-version: '11'
59+
60+
- name: Import GPG key
61+
uses: crazy-max/ghaction-import-gpg@v6
62+
with:
63+
gpg_private_key: ${{ secrets.PARQUET_GPG_PRIVATE_KEY }}
64+
65+
- name: Install Subversion
66+
run: sudo apt-get update && sudo apt-get install -y subversion
67+
68+
- name: Configure Git
69+
run: |
70+
git config --global user.name "github-actions[bot]"
71+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
72+
73+
- name: Prepare Release Candidate
74+
env:
75+
DRY_RUN: ${{ inputs.dry_run && '1' || '0' }}
76+
NEXUS_USERNAME: ${{ secrets.PARQUET_NEXUS_USER }}
77+
NEXUS_PASSWORD: ${{ secrets.PARQUET_NEXUS_PASSWORD }}
78+
SVN_USERNAME: ${{ secrets.PARQUET_SVN_DEV_USERNAME }}
79+
SVN_PASSWORD: ${{ secrets.PARQUET_SVN_DEV_PASSWORD }}
80+
GPG_PASSPHRASE: ${{ secrets.PARQUET_GPG_PASSPHRASE }}
81+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
82+
INPUT_VERSION: ${{ inputs.version }}
83+
INPUT_RC_NUMBER: ${{ inputs.rc_number }}
84+
run: |
85+
args=("${INPUT_VERSION}")
86+
if [[ -n "${INPUT_RC_NUMBER}" ]]; then
87+
args+=(--rc "${INPUT_RC_NUMBER}")
88+
fi
89+
./release/bin/prepare-rc.sh "${args[@]}"
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
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+
name: Release - Publish After Vote
21+
22+
on:
23+
workflow_dispatch:
24+
inputs:
25+
version:
26+
description: 'Release version (e.g., 1.18.0)'
27+
required: true
28+
type: string
29+
rc_number:
30+
description: 'RC number that passed the vote (leave empty to auto-detect latest)'
31+
required: false
32+
type: string
33+
default: ''
34+
staging_repo_id:
35+
description: 'Nexus staging repository ID (e.g., orgapacheparquet-1234)'
36+
required: true
37+
type: string
38+
next_dev_version:
39+
description: 'Next development version without -SNAPSHOT (e.g., 1.18.1 or 1.19.0)'
40+
required: true
41+
type: string
42+
dry_run:
43+
description: 'Dry run mode (no actual changes)'
44+
required: false
45+
type: boolean
46+
default: true
47+
48+
jobs:
49+
publish-release:
50+
name: Publish Release
51+
runs-on: ubuntu-latest
52+
permissions:
53+
contents: write
54+
55+
steps:
56+
- name: Checkout repository
57+
uses: actions/checkout@v4
58+
with:
59+
fetch-depth: 0
60+
token: ${{ secrets.GITHUB_TOKEN }}
61+
62+
- name: Set up JDK 11
63+
uses: actions/setup-java@v4
64+
with:
65+
distribution: temurin
66+
java-version: '11'
67+
68+
- name: Install Subversion
69+
run: sudo apt-get update && sudo apt-get install -y subversion
70+
71+
- name: Configure Git
72+
run: |
73+
git config --global user.name "github-actions[bot]"
74+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
75+
76+
- name: Publish Release
77+
env:
78+
DRY_RUN: ${{ inputs.dry_run && '1' || '0' }}
79+
NEXUS_USERNAME: ${{ secrets.PARQUET_NEXUS_USER }}
80+
NEXUS_PASSWORD: ${{ secrets.PARQUET_NEXUS_PASSWORD }}
81+
SVN_USERNAME: ${{ secrets.PARQUET_SVN_DEV_USERNAME }}
82+
SVN_PASSWORD: ${{ secrets.PARQUET_SVN_DEV_PASSWORD }}
83+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
84+
INPUT_VERSION: ${{ inputs.version }}
85+
INPUT_RC_NUMBER: ${{ inputs.rc_number }}
86+
INPUT_STAGING_REPO_ID: ${{ inputs.staging_repo_id }}
87+
INPUT_NEXT_DEV_VERSION: ${{ inputs.next_dev_version }}
88+
run: |
89+
args=("${INPUT_VERSION}" "${INPUT_STAGING_REPO_ID}" "${INPUT_NEXT_DEV_VERSION}")
90+
if [[ -n "${INPUT_RC_NUMBER}" ]]; then
91+
args+=(--rc "${INPUT_RC_NUMBER}")
92+
fi
93+
./release/bin/publish-release.sh "${args[@]}"

0 commit comments

Comments
 (0)