Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .asf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ project:
programming_languages:
- Rust
policy:
github_repository_name: asyncband
github_compose_workflow_path:
- .github/workflows/release-compose.yml
source_artifact_paths:
- "apache-asyncband-*-incubating-src.tar.gz"
vote_mode: email
Expand Down
145 changes: 145 additions & 0 deletions .github/workflows/release-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# 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: Compose source release

on:
push:
tags: [ "v*.*.*-rc.*" ]
pull_request:
paths:
- .github/workflows/release-compose.yml
- .asf.yaml

permissions:
contents: read
id-token: write

defaults:
run:
shell: bash

env:
LC_ALL: C

concurrency:
group: source-release-${{ github.event_name == 'pull_request' && github.event.number || 'compose' }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
compose:
name: Compose source release
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
- id: source
name: Archive the release candidate
run: |
set -euo pipefail
commit="$(git rev-parse HEAD)"
package_version="$(git show "${commit}:asyncband/Cargo.toml" | python3 -c 'import sys, tomllib; print(tomllib.loads(sys.stdin.read())["package"]["version"])')"
if [[ "${GITHUB_EVENT_NAME}" == push ]]; then
if [[ ! "${GITHUB_REF_NAME}" =~ ^v([0-9]+\.[0-9]+\.[0-9]+)-rc\.([1-9][0-9]*)$ ]]; then
echo "::error::Expected an RC tag named vX.Y.Z-rc.N with a positive RC number."
exit 1
fi
version="${BASH_REMATCH[1]}"
if [[ "${version}" != "${package_version}" ]]; then
echo "::error::Tag ${GITHUB_REF_NAME} does not match package version ${package_version}."
exit 1
fi
test "$(git rev-parse "${GITHUB_REF}^{commit}")" = "${commit}"
git merge-base --is-ancestor "${commit}" origin/main
else
version="${package_version}"
fi
if [[ ! "${version}" =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]]; then
echo "::error::The package must have a stable X.Y.Z version."
exit 1
fi
source="apache-asyncband-${version}-incubating-src"
mkdir "${RUNNER_TEMP}/source"
git -c core.attributesFile=/dev/null -c tar.umask=0022 archive \
--format=tar --prefix="${source}/" "${commit}" \
| gzip -n -9 > "${RUNNER_TEMP}/source/${source}.tar.gz"
cd "${RUNNER_TEMP}/source"
shasum -a 512 "${source}.tar.gz" > "${source}.tar.gz.sha512"
echo "commit=${commit}" >> "${GITHUB_OUTPUT}"
echo "version=${version}" >> "${GITHUB_OUTPUT}"
echo "archive=${source}.tar.gz" >> "${GITHUB_OUTPUT}"
{
echo "Source ref: ${GITHUB_REF}"
echo "Source commit: ${commit}"
echo
cat "${source}.tar.gz.sha512"
} >> "${GITHUB_STEP_SUMMARY}"
- id: sign
name: Sign with the ASF project key
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && github.repository == 'apache/asyncband' }}
env:
ARCHIVE: ${{ steps.source.outputs.archive }}
SIGNING_KEY: ${{ secrets.GPG_SECRET_KEY }}
SIGNING_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
SIGNING_FINGERPRINT: ${{ vars.SOURCE_SIGNING_FINGERPRINT }}
run: |
set -euo pipefail
: "${SIGNING_KEY:?Configure the ASF project key in GPG_SECRET_KEY.}"
if [[ ! "${SIGNING_FINGERPRINT}" =~ ^([0-9A-F]{40}|[0-9A-F]{64})$ ]]; then
echo "::error::SOURCE_SIGNING_FINGERPRINT must be the full uppercase primary fingerprint."
exit 1
fi
cd "${RUNNER_TEMP}/source"
GNUPGHOME="$(mktemp -d "${RUNNER_TEMP}/gnupg.XXXXXX")"
export GNUPGHOME
trap 'gpgconf --kill gpg-agent; rm -rf -- "${GNUPGHOME}"' EXIT
printf '%s' "${SIGNING_KEY}" | gpg --batch --import
unset SIGNING_KEY
gpg --batch --list-secret-keys "${SIGNING_FINGERPRINT}"
printf '%s' "${SIGNING_PASSPHRASE}" | gpg --batch --pinentry-mode loopback \
--passphrase-fd 0 --armor --detach-sign --local-user "${SIGNING_FINGERPRINT}" "${ARCHIVE}"
gpg --batch --status-fd 1 --verify "${ARCHIVE}.asc" "${ARCHIVE}" \
| awk -v fingerprint="${SIGNING_FINGERPRINT}" \
'$2 == "VALIDSIG" && ($3 == fingerprint || $NF == fingerprint) { valid = 1 } END { exit !valid }'
- name: Upload to ATR compose
if: ${{ steps.sign.outcome == 'success' }}
uses: apache/tooling-actions/upload-to-atr@fa721a0b176d713807b574da721b96545b587eea
with:
project: asyncband
version: ${{ steps.source.outputs.version }}
src: ${{ runner.temp }}/source
- name: Record the candidate handoff
if: ${{ steps.sign.outcome == 'success' }}
env:
SOURCE_COMMIT: ${{ steps.source.outputs.commit }}
VERSION: ${{ steps.source.outputs.version }}
ARCHIVE: ${{ steps.source.outputs.archive }}
run: |
{
echo "Uploaded RC tag ${GITHUB_REF_NAME} (${SOURCE_COMMIT}) to ATR project asyncband, version ${VERSION}."
echo
cat "${RUNNER_TEMP}/source/${ARCHIVE}.sha512"
echo
echo "Inspect ATR checks and record the candidate URL and revision before starting a vote."
echo "Inspect ATR before rerunning this job after an upload failure; reruns rebuild and re-sign the same RC tag."
} >> "${GITHUB_STEP_SUMMARY}"