blob: fde05b61e6c2c7276279a9b7ceb6b665536ae797 [file] [log] [blame]
#
# 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: deploy-release-reusable
on:
workflow_call:
inputs:
java-version:
description: The Java compiler version
default: 17
type: string
project-id:
description: Identifier used in the distribution artifact and Subversion repository folder filenames (e.g., `logging-parent`)
required: true
type: string
secrets:
GPG_SECRET_KEY:
description: GPG secret key for signing artifacts
required: true
NEXUS_USERNAME:
description: Nexus staging repository username for deploying artifacts
required: true
NEXUS_PASSWORD:
description: Nexus staging repository password for deploying artifacts
required: true
SVN_USERNAME:
description: Subversion username for uploading the release distribution
required: true
SVN_PASSWORD:
description: Subversion password for uploading the release distribution
required: true
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
- name: Set up Java & GPG
uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # 3.7.0
with:
distribution: zulu
java-version: ${{ inputs.java-version }}
cache: maven
server-id: apache.releases.https
server-username: NEXUS_USERNAME
server-password: NEXUS_PASSWORD
gpg-private-key: ${{ secrets.GPG_SECRET_KEY }}
- name: Set up Git user
shell: bash
run: |
# Set up user name and email required for `git commit`
git config user.name "ASF Logging Services RM"
git config user.email private@logging.apache.org
- name: Export version
shell: bash
env:
GIT_BRANCH_NAME: ${{ github.ref_name }}
run: |
[[ "$GIT_BRANCH_NAME" =~ ^release/.+$ ]] || {
echo "was expecting a \`release/\`-prefixed Git branch name, found: \`$GIT_BRANCH_NAME\`"
exit 1
}
export PROJECT_VERSION=$(echo "$GIT_BRANCH_NAME" | sed 's/^release\///')
echo "PROJECT_VERSION=$PROJECT_VERSION" >> $GITHUB_ENV
- name: Set the Maven `revision` property
shell: bash
run: |
export REVISION=$(./mvnw \
--non-recursive --quiet --batch-mode \
-DforceStdout=true \
-Dexpression=revision \
help:evaluate \
| tail -n 1)
if [ "$REVISION" != "$PROJECT_VERSION" ]; then
echo "Maven \`revision\` property \`$REVISION\` doesn't match with the project version \`$PROJECT_VERSION\`, updating \`pom.xml\`..."
./mvnw \
--non-recursive --batch-mode --errors --no-transfer-progress \
-Dproperty=revision \
-DnewVersion="$PROJECT_VERSION" \
-DgenerateBackupPoms=false \
versions:set-property
git commit -S pom.xml -m "Set version to \`$PROJECT_VERSION\`"
git push -f origin
fi
- name: Set the Maven `project.build.outputTimestamp` property
shell: bash
run: |
export PROPERTY="project.build.outputTimestamp"
grep -qE '^[\t ]+<'$PROPERTY'>' pom.xml || {
echo "Failed to find the \`$PROPERTY\` Maven property!"
exit 1
}
export TIMESTAMP=$(TZ=UTC0 git show --quiet --date="format-local:%Y-%m-%dT%H:%M:%SZ" --format="%cd")
sed -r 's|^([\t ]+<'$PROPERTY'>).+(</'$PROPERTY'>)$|\1'$TIMESTAMP'\2|g' -i pom.xml
if [ -n "$(git status --porcelain)" ]; then
git commit -S pom.xml -m "Update the \`$PROPERTY\` property"
git push -f origin
fi
- name: Release changelog
shell: bash
run: |
./mvnw \
--non-recursive --batch-mode --errors --no-transfer-progress \
-P changelog-release
git add src
if [ -n "$(git status --porcelain)" ]; then
git commit -S src -m "Release changelog for version \`$PROJECT_VERSION\`"
git push -f origin
fi
- name: Upload to Nexus
shell: bash
env:
# `NEXUS_USERNAME` and `NEXUS_PASSWORD` are used in `~/.m2/settings.xml` created by `setup-java` action
NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }}
NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }}
# `SIGN_KEY` is used by `sign-maven-plugin`
SIGN_KEY: ${{ secrets.GPG_SECRET_KEY }}
run: |
./mvnw \
--show-version --batch-mode --errors --no-transfer-progress \
-P deploy,release
export NEXUS_URL=$(awk '/^(stagingRepository.url)/ { gsub(/(^.+=|\\)/, ""); print $1 }' target/nexus-staging/staging/*.properties)
echo "NEXUS_URL=$NEXUS_URL" >> $GITHUB_ENV
# Node.js cache is needed for Antora
- name: Set up Node.js cache
id: nodejs-cache
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # 4.1.1
with:
# We should be calculating the cache key using `package-lock.json` instead!
# See https://stackoverflow.com/a/48524475/1278899
# For that, `package-lock.json` needs to be committed into the repository – right now it is `.gitignore`d.
# Once it is there, we should ideally switch from `npm i` to `npm ci`.
# For that, we need to configure `dependabot` to update hundreds of dependencies listed in `package-lock.json`.
# That translates to a never ending rain of `dependabot` PRs.
# I doubt if the wasted CPU cycles worth the gain.
key: ${{ runner.os }}-nodejs-cache-${{ hashFiles('node', 'node_modules') }}
# `actions/cache` doesn't recommend caching `node_modules`.
# Though none of its recipes fit our bill, since we install Node.js using `frontend-maven-plugin`.
# See https://github.com/actions/cache/blob/main/examples.md#node---npm
# We settle for this quick-n-dirty solution for the time being.
path: |
node
node_modules
# Website build is needed to generate the release notes
- name: Build the website
shell: bash
env:
# Making Node.js cache hit visible for debugging purposes
NODEJS_CACHE_HIT: ${{ steps.nodejs-cache.outputs.cache-hit }}
run: |
export TIMESTAMP=$(./mvnw \
--non-recursive --quiet --batch-mode \
-DforceStdout=true \
-Dexpression=project.build.outputTimestamp \
help:evaluate \
| tail -n 1)
./mvnw \
--show-version --batch-mode --errors --no-transfer-progress \
site
- name: Stage distribution attachments
shell: bash
run: |
# Dump deployed artifacts to a local folder
export ALT_DEPLOYMENT_REPO_FILEPATH="target/alt-deployment-repo"
mkdir "$ALT_DEPLOYMENT_REPO_FILEPATH"
./mvnw \
--show-version --batch-mode --errors --no-transfer-progress \
-DaltDeploymentRepository=apache.releases.https::file:"$ALT_DEPLOYMENT_REPO_FILEPATH" \
-Dsign.skip \
-P deploy
# This regex needs to work for both Java (`distribution` profile) and `find` (while counting attachments)!
# Hence, we don't escape dots, etc. with backslashes, which is problematic to get working in both worlds.
export DIST_ATTACHMENT_FILEPATH_PATTERN="^$ALT_DEPLOYMENT_REPO_FILEPATH/.+-$PROJECT_VERSION"'((-tests)?.jar|-cyclonedx.xml)$'
export DIST_ATTACHMENT_COUNT=$(find "$ALT_DEPLOYMENT_REPO_FILEPATH" -type f -regextype posix-extended -regex "$DIST_ATTACHMENT_FILEPATH_PATTERN" | wc -l)
# Pass the necessary environment variables
cat >> $GITHUB_ENV << EOF
DIST_ATTACHMENT_FILEPATH_PATTERN=$DIST_ATTACHMENT_FILEPATH_PATTERN
DIST_ATTACHMENT_COUNT=$DIST_ATTACHMENT_COUNT
EOF
- name: Create the distribution
shell: bash
run: |
# Generate the distribution (i.e., `src.zip` and optional `bin.zip`)
./mvnw \
--show-version --batch-mode --errors --no-transfer-progress \
--non-recursive \
-P distribution \
-DattachmentFilepathPattern="$DIST_ATTACHMENT_FILEPATH_PATTERN" \
-DattachmentCount="$DIST_ATTACHMENT_COUNT"
# Rename distribution files
export DIST_FILENAME_PREFIX="apache-${{ inputs.project-id }}"
export DIST_FILENAME_VERSIONED_PREFIX="${DIST_FILENAME_PREFIX}-${PROJECT_VERSION}"
export DIST_FILEPATH_PREFIX="/tmp/${DIST_FILENAME_VERSIONED_PREFIX}"
export DIST_FILEPATH_SRC="${DIST_FILEPATH_PREFIX}-src.zip"
export DIST_FILEPATH_BIN="${DIST_FILEPATH_PREFIX}-bin.zip"
mv "target/src.zip" "$DIST_FILEPATH_SRC"
test -f "target/bin.zip" && mv "$_" "$DIST_FILEPATH_BIN"
# Create signature and checksum files
for DIST_FILEPATH in "$DIST_FILEPATH_SRC" "$DIST_FILEPATH_BIN"; do
if [ -f "$DIST_FILEPATH" ]; then
gpg --armor --detach-sign --yes --pinentry-mode error "$DIST_FILEPATH"
sha512sum "$DIST_FILEPATH" \
| ( read CHECKSUM FILEPATH; echo $CHECKSUM" "$(basename "$FILEPATH") ) \
> "$DIST_FILEPATH.sha512"
fi
done
# Pass the necessary environment variables
cat >> $GITHUB_ENV << EOF
DIST_FILENAME_PREFIX=$DIST_FILENAME_PREFIX
DIST_FILENAME_VERSIONED_PREFIX=$DIST_FILENAME_VERSIONED_PREFIX
DIST_FILEPATH_PREFIX=$DIST_FILEPATH_PREFIX
EOF
- name: Upload to Subversion
shell: bash
env:
PROJECT_ID: ${{ inputs.project-id }}
SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
run: |
# Find the effective Git commit ID
export COMMIT_ID=$(git rev-parse HEAD)
# Checkout the SVN repository
export SVN_DIR="/tmp/svn-repo"
svn co \
"https://dist.apache.org/repos/dist/dev/logging/$PROJECT_ID" \
"$SVN_DIR"
cd "$SVN_DIR"
# Switch to the distribution folder
[ -d "$PROJECT_VERSION" ] || {
mkdir "$PROJECT_VERSION"
svn add "$PROJECT_VERSION"
}
cd "$PROJECT_VERSION"
# Clean up old files
find . -name "${DIST_FILENAME_PREFIX}*" -type f -print0 | xargs -0 -r svn delete
# Generate emails
for EMAIL_TYPE in vote announce; do
"$GITHUB_WORKSPACE/.github/generate-email.sh" \
"$EMAIL_TYPE" "$PROJECT_VERSION" "$COMMIT_ID" "$NEXUS_URL" \
> "${DIST_FILENAME_VERSIONED_PREFIX}-email-${EMAIL_TYPE}.txt"
done
# Copy the distribution
cp "$DIST_FILEPATH_PREFIX"* .
# Add & commit changes
svn add "$DIST_FILENAME_PREFIX"*
svn commit \
--username "$SVN_USERNAME" \
--password "$SVN_PASSWORD" \
-m "Added \`${DIST_FILENAME_PREFIX}\` artifacts for release \`${PROJECT_VERSION}\`"