Skip to content

fix(ci): harden publish pipeline (#3125) #520

fix(ci): harden publish pipeline (#3125)

fix(ci): harden publish pipeline (#3125) #520

Workflow file for this run

# 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.
# Auto-publish: detects pre-release crate/SDK versions without tags
# and publishes them to crates.io, Docker Hub, PyPI, npm, Maven, NuGet.
# Runs on every push to master.
name: Post-merge
on:
push:
branches: [master]
permissions:
contents: write
packages: write
id-token: write
concurrency:
group: post-merge-${{ github.ref }}
cancel-in-progress: false
env:
IGGY_CI_BUILD: true
jobs:
check-auto-publish:
name: Check auto-publish
runs-on: ubuntu-latest
if: ${{ !github.event.repository.fork }}
outputs:
docker_components: ${{ steps.check.outputs.docker_components }}
crates_to_publish: ${{ steps.check.outputs.crates_to_publish }}
sdks_to_publish: ${{ steps.check.outputs.sdks_to_publish }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup yq
run: |
if ! command -v yq >/dev/null 2>&1; then
YQ_VERSION="v4.47.1"
YQ_CHECKSUM="0fb28c6680193c41b364193d0c0fc4a03177aecde51cfc04d506b1517158c2fb"
curl -sSL -o /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64
echo "${YQ_CHECKSUM} /usr/local/bin/yq" | sha256sum -c - || exit 1
chmod +x /usr/local/bin/yq
fi
- name: Check all components
id: check
run: |
chmod +x scripts/extract-version.sh
# Get all Docker components (always publish :edge)
DOCKER_COMPONENTS=$(yq -r '.components | to_entries | .[] | select(.value.registry == "dockerhub") | .key' .github/config/publish.yml | tr '\n' ',' | sed 's/,$//')
echo "docker_components=$DOCKER_COMPONENTS" >> "$GITHUB_OUTPUT"
echo "Docker components: $DOCKER_COMPONENTS"
# Check Rust crates for pre-release versions without tags
CRATES_TO_PUBLISH=""
for crate in rust-common rust-binary-protocol rust-sdk rust-cli; do
VERSION=$(scripts/extract-version.sh "$crate")
TAG=$(scripts/extract-version.sh "$crate" --tag)
echo "Checking $crate: version=$VERSION, tag=$TAG"
if [ "$(scripts/extract-version.sh "$crate" --is-pre-release)" != "true" ]; then
echo " ⏭️ Stable version - skipping"
continue
fi
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo " ⏭️ Tag exists - skipping"
continue
fi
echo " ✅ Will publish"
CRATES_TO_PUBLISH="${CRATES_TO_PUBLISH:+$CRATES_TO_PUBLISH,}$crate"
done
echo "crates_to_publish=$CRATES_TO_PUBLISH" >> "$GITHUB_OUTPUT"
echo "Crates to publish: ${CRATES_TO_PUBLISH:-<none>}"
# Check SDKs for pre-release versions without tags
SDKS_TO_PUBLISH=""
for sdk in sdk-python sdk-node sdk-java sdk-csharp sdk-go; do
VERSION=$(scripts/extract-version.sh "$sdk")
TAG=$(scripts/extract-version.sh "$sdk" --tag)
echo "Checking $sdk: version=$VERSION, tag=$TAG"
# Maven SNAPSHOT versions are mutable -- republish when SDK sources change,
# skip tag gate since no tag will be created for SNAPSHOTs
if [[ "$VERSION" =~ -SNAPSHOT$ ]]; then
SDK_NAME="${sdk#sdk-}"
SDK_DIR="foreign/$SDK_NAME"
if ! git diff --name-only HEAD~1 HEAD -- "$SDK_DIR/" | grep -q .; then
echo " ⏭️ SNAPSHOT - no changes in $SDK_DIR/"
continue
fi
echo " ✅ SNAPSHOT version - will publish"
SDKS_TO_PUBLISH="${SDKS_TO_PUBLISH:+$SDKS_TO_PUBLISH,}$SDK_NAME"
continue
fi
if [ "$(scripts/extract-version.sh "$sdk" --is-pre-release)" != "true" ]; then
echo " ⏭️ Stable version - skipping"
continue
fi
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo " ⏭️ Tag exists - skipping"
continue
fi
echo " ✅ Will publish"
# Convert sdk-csharp to csharp for publish.yml input format
SDK_NAME="${sdk#sdk-}"
SDKS_TO_PUBLISH="${SDKS_TO_PUBLISH:+$SDKS_TO_PUBLISH,}$SDK_NAME"
done
echo "sdks_to_publish=$SDKS_TO_PUBLISH" >> "$GITHUB_OUTPUT"
echo "SDKs to publish: ${SDKS_TO_PUBLISH:-<none>}"
call-publish:
name: Publish components
needs: check-auto-publish
uses: ./.github/workflows/publish.yml
with:
commit: ${{ github.sha }}
dry_run: false
use_latest_ci: false
skip_tag_creation: false
publish_crates: ${{ needs.check-auto-publish.outputs.crates_to_publish }}
publish_dockerhub: ${{ needs.check-auto-publish.outputs.docker_components }}
publish_other: ${{ needs.check-auto-publish.outputs.sdks_to_publish }}
create_edge_docker_tag: true
secrets: inherit