Skip to content

v0.11.3

v0.11.3 #57

Workflow file for this run

name: Multi-module Release
on:
release:
types: [published]
env:
GROUP_ID: io.testomat
MAVEN_CENTRAL_BASE: https://repo1.maven.org/maven2
MAVEN_SEARCH_BASE: https://search.maven.org/remotecontent
MAVEN_SEARCH_API: https://search.maven.org/solrsearch/select
MAVEN_TIMEOUT: 3600
MAVEN_CENTRAL_WAIT_TIMEOUT: 7200
MAX_RETRY_ATTEMPTS: 3
RETRY_DELAY: 30
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Validate project structure
run: |
set -e
REQUIRED_DIRS=("java-reporter-core" "java-reporter-junit" "java-reporter-testng" "java-reporter-cucumber" "java-reporter-karate" "testomat-allure-adapter")
for dir in "${REQUIRED_DIRS[@]}"; do
if [[ ! -d "$dir" ]] || [[ ! -f "$dir/pom.xml" ]]; then
echo "❌ Missing: $dir"
exit 1
fi
done
echo "✅ Project structure OK"
- name: Validate required secrets
run: |
set -e
MISSING_SECRETS=()
[[ -z "${{ secrets.GPG_PRIVATE_KEY }}" ]] && MISSING_SECRETS+=("GPG_PRIVATE_KEY")
[[ -z "${{ secrets.CENTRAL_USERNAME }}" ]] && MISSING_SECRETS+=("CENTRAL_USERNAME")
[[ -z "${{ secrets.CENTRAL_PASSWORD }}" ]] && MISSING_SECRETS+=("CENTRAL_PASSWORD")
[[ -z "${{ secrets.GPG_PASSPHRASE }}" ]] && MISSING_SECRETS+=("GPG_PASSPHRASE")
if [[ ${#MISSING_SECRETS[@]} -gt 0 ]]; then
echo "❌ Missing secrets: ${MISSING_SECRETS[*]}"
exit 1
fi
echo "✅ Secrets OK"
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Cache Maven dependencies
uses: actions/cache@v4
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: Configure Maven settings
run: |
set -e
mkdir -p ~/.m2
cat > ~/.m2/settings.xml << 'EOF'
<settings>
<servers>
<server>
<id>central</id>
<username>${env.CENTRAL_USERNAME}</username>
<password>${env.CENTRAL_PASSWORD}</password>
</server>
</servers>
</settings>
EOF
echo "✅ Maven settings configured"
- name: Get version from release tag
id: version
run: |
set -e
TAG_NAME="${{ github.event.release.tag_name }}"
if [[ -z "$TAG_NAME" ]]; then
echo "❌ No tag name"
exit 1
fi
VERSION=${TAG_NAME#v}
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$'; then
echo "❌ Invalid version: $VERSION"
exit 1
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "✅ Version: $VERSION"
- name: Set versions in all modules
run: |
set -e
VERSION=${{ steps.version.outputs.version }}
echo "🔄 Setting version $VERSION in all modules individually..."
# List of all modules (each has its own pom.xml)
MODULES=("java-reporter-core" "java-reporter-junit" "java-reporter-testng" "java-reporter-cucumber" "java-reporter-karate" "testomat-allure-adapter")
for module in "${MODULES[@]}"; do
if [[ -d "$module" && -f "$module/pom.xml" ]]; then
echo "Setting version in $module..."
cd "$module" || { echo "❌ Cannot enter $module"; exit 1; }
# Set version in this module
if ! mvn versions:set -DnewVersion="$VERSION" -DgenerateBackupPoms=false -B; then
echo "❌ Failed to set version in $module"
exit 1
fi
echo "✅ Version set to $VERSION in $module"
cd .. || exit 1
else
echo "⚠️ Module $module not found or missing pom.xml"
fi
done
echo "✅ All module versions set to $VERSION"
- name: Update internal dependencies (excluding Core)
run: |
set -e
VERSION=${{ steps.version.outputs.version }}
echo "🔄 Updating internal dependencies to version $VERSION..."
# Only modules that have internal dependencies (excluding Core)
MODULES_WITH_DEPS=("java-reporter-junit" "java-reporter-testng" "java-reporter-cucumber" "java-reporter-karate" "testomat-allure-adapter")
for module in "${MODULES_WITH_DEPS[@]}"; do
if [[ -d "$module" && -f "$module/pom.xml" ]]; then
echo "Updating dependencies in $module..."
cd "$module" || continue
# Update java-reporter-core dependency (most modules depend on it)
echo " Updating java-reporter-core dependency..."
if mvn versions:use-dep-version \
-Dincludes="${{ env.GROUP_ID }}:java-reporter-core" \
-DdepVersion="$VERSION" \
-DforceVersion=true \
-DgenerateBackupPoms=false \
-B 2>/dev/null; then
echo " ✅ Updated java-reporter-core to $VERSION"
else
echo " ⚠️ java-reporter-core dependency not found"
fi
cd .. || exit 1
fi
done
echo "✅ All internal dependencies updated"
- name: Verify all versions are set correctly
run: |
set -e
VERSION=${{ steps.version.outputs.version }}
echo "🔍 Verifying all module versions are set to $VERSION..."
MODULES=("java-reporter-core" "java-reporter-junit" "java-reporter-testng" "java-reporter-cucumber" "java-reporter-karate" "testomat-allure-adapter")
FAILED_MODULES=()
for module in "${MODULES[@]}"; do
if [[ -d "$module" && -f "$module/pom.xml" ]]; then
cd "$module" || continue
CURRENT_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout 2>/dev/null)
if [[ "$CURRENT_VERSION" == "$VERSION" ]]; then
echo "✅ $module version: $CURRENT_VERSION"
else
echo "❌ $module version mismatch: expected $VERSION, got $CURRENT_VERSION"
FAILED_MODULES+=("$module")
fi
cd .. || exit 1
fi
done
if [[ ${#FAILED_MODULES[@]} -gt 0 ]]; then
echo "❌ Version verification failed for modules: ${FAILED_MODULES[*]}"
exit 1
fi
echo "✅ All module versions verified successfully"
- name: Setup GPG
run: |
set -e
echo "${{ secrets.GPG_PRIVATE_KEY }}" | base64 --decode | gpg --batch --import
echo "✅ GPG configured"
- name: Deploy Core module
run: |
set -e
echo "🚀 Deploying Core..."
cd java-reporter-core || { echo "❌ Cannot enter core directory"; exit 1; }
# Verify version is set correctly
CURRENT_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
if [[ "$CURRENT_VERSION" != "${{ steps.version.outputs.version }}" ]]; then
echo "❌ Version mismatch: expected ${{ steps.version.outputs.version }}, got $CURRENT_VERSION"
exit 1
fi
for i in $(seq 1 ${{ env.MAX_RETRY_ATTEMPTS }}); do
echo "Core deployment attempt $i..."
if timeout ${{ env.MAVEN_TIMEOUT }} mvn clean deploy -P release -DskipTests -B; then
echo "✅ Core deployed successfully"
cd .. || exit 1
break
elif [[ $i -eq ${{ env.MAX_RETRY_ATTEMPTS }} ]]; then
echo "❌ Core deployment failed after ${{ env.MAX_RETRY_ATTEMPTS }} attempts"
cd .. || exit 1
exit 1
else
echo "Retrying in ${{ env.RETRY_DELAY }}s..."
sleep ${{ env.RETRY_DELAY }}
fi
done
env:
CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }}
CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
- name: Wait for Core availability
run: |
set -e
VERSION=${{ steps.version.outputs.version }}
MODULE="java-reporter-core"
GROUP_PATH=$(echo "${{ env.GROUP_ID }}" | tr '.' '/')
echo "⏳ Waiting for Core availability..."
WAIT_ITERATIONS=$((MAVEN_CENTRAL_WAIT_TIMEOUT / 120))
for i in $(seq 1 $WAIT_ITERATIONS); do
echo "Checking availability attempt $i/$WAIT_ITERATIONS..."
# Check Maven Central directly
if curl -s -f --max-time 30 "${{ env.MAVEN_CENTRAL_BASE }}/$GROUP_PATH/$MODULE/$VERSION/$MODULE-$VERSION.pom" >/dev/null 2>&1; then
echo "✅ Core available on Maven Central"
break
fi
# Try dependency resolution
if timeout 60 mvn dependency:get -Dartifact="${{ env.GROUP_ID }}:$MODULE:$VERSION" -B >/dev/null 2>&1; then
echo "✅ Core available via Maven dependency resolution"
break
fi
if [[ $i -eq $WAIT_ITERATIONS ]]; then
echo "❌ Core not available after waiting"
exit 1
fi
echo "Core not yet available, waiting 2 minutes..."
sleep 120
done
- name: Deploy Framework modules
run: |
set -e
VERSION=${{ steps.version.outputs.version }}
echo "🚀 Deploying Framework modules..."
# Create temporary directory for logs
mkdir -p /tmp/deploy_logs
deploy_framework_module() {
local module="$1"
local log_file="/tmp/deploy_logs/${module}.log"
{
echo "Deploying $module..."
cd "$module" || exit 1
# Verify version is set correctly
CURRENT_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
if [[ "$CURRENT_VERSION" != "$VERSION" ]]; then
echo "❌ Version mismatch in $module: expected $VERSION, got $CURRENT_VERSION"
exit 1
fi
# Simple verification that core dependency exists and will be updated
echo "Verifying java-reporter-core dependency in $module..."
if grep -q "java-reporter-core" pom.xml; then
echo "✅ Core dependency found in $module"
# Force update core dependency to ensure correct version
mvn versions:use-dep-version \
-Dincludes="${{ env.GROUP_ID }}:java-reporter-core" \
-DdepVersion="$VERSION" \
-DforceVersion=true \
-DgenerateBackupPoms=false \
-B || echo "⚠️ Failed to update core dependency"
else
echo "ℹ️ No core dependency found in $module (normal for core module itself)"
fi
# Deploy module
for i in $(seq 1 ${{ env.MAX_RETRY_ATTEMPTS }}); do
echo "Deployment attempt $i for $module"
if timeout ${{ env.MAVEN_TIMEOUT }} mvn clean deploy -P release -DskipTests -B; then
echo "$module deployed successfully"
cd .. || exit 1
exit 0
elif [[ $i -eq ${{ env.MAX_RETRY_ATTEMPTS }} ]]; then
echo "$module deployment failed after ${{ env.MAX_RETRY_ATTEMPTS }} attempts"
exit 1
else
sleep ${{ env.RETRY_DELAY }}
fi
done
} > "$log_file" 2>&1
}
# Export function and variables for subshells
export -f deploy_framework_module
export VERSION
export MAVEN_TIMEOUT=${{ env.MAVEN_TIMEOUT }}
export MAX_RETRY_ATTEMPTS=${{ env.MAX_RETRY_ATTEMPTS }}
export RETRY_DELAY=${{ env.RETRY_DELAY }}
# Deploy modules in parallel
deploy_framework_module "java-reporter-junit" &
JUNIT_PID=$!
deploy_framework_module "java-reporter-testng" &
TESTNG_PID=$!
deploy_framework_module "java-reporter-cucumber" &
CUCUMBER_PID=$!
deploy_framework_module "java-reporter-karate" &
KARATE_PID=$!
deploy_framework_module "testomat-allure-adapter" &
TAADAPTER_PID=$!
# Wait for all modules and collect results
FAILED_MODULES=()
if ! wait $JUNIT_PID; then
FAILED_MODULES+=("junit")
echo "❌ JUnit deployment failed"
cat /tmp/deploy_logs/java-reporter-junit.log
else
echo "✅ JUnit deployed"
fi
if ! wait $TESTNG_PID; then
FAILED_MODULES+=("testng")
echo "❌ TestNG deployment failed"
cat /tmp/deploy_logs/java-reporter-testng.log
else
echo "✅ TestNG deployed"
fi
if ! wait $CUCUMBER_PID; then
FAILED_MODULES+=("cucumber")
echo "❌ Cucumber deployment failed"
cat /tmp/deploy_logs/java-reporter-cucumber.log
else
echo "✅ Cucumber deployed"
fi
if ! wait $KARATE_PID; then
FAILED_MODULES+=("karate")
cat /tmp/deploy_logs/java-reporter-karate.log
else
echo "✅ Karate deployed"
fi
if ! wait $TAADAPTER_PID; then
FAILED_MODULES+=("taadapter")
cat /tmp/deploy_logs/testomat-allure-adapter.log
else
echo "✅ Testomat Allure adapter deployed"
fi
# Cleanup logs
rm -rf /tmp/deploy_logs
if [[ ${#FAILED_MODULES[@]} -gt 0 ]]; then
echo "❌ Failed modules: ${FAILED_MODULES[*]}"
exit 1
fi
echo "✅ All Framework modules deployed successfully"
env:
CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }}
CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
- name: Wait for Framework availability
run: |
set -e
VERSION=${{ steps.version.outputs.version }}
GROUP_PATH=$(echo "${{ env.GROUP_ID }}" | tr '.' '/')
modules=("java-reporter-junit" "java-reporter-testng" "java-reporter-cucumber" "java-reporter-karate" "testomat-allure-adapter")
echo "⏳ Waiting for Framework modules availability..."
WAIT_ITERATIONS=$((MAVEN_CENTRAL_WAIT_TIMEOUT / 120 / 3))
for module in "${modules[@]}"; do
echo "Checking $module availability..."
for i in $(seq 1 $WAIT_ITERATIONS); do
# Check Maven Central
if curl -s -f --max-time 30 "${{ env.MAVEN_CENTRAL_BASE }}/$GROUP_PATH/$module/$VERSION/$module-$VERSION.pom" >/dev/null 2>&1; then
echo "✅ $module available"
break
fi
# Try dependency resolution
if timeout 60 mvn dependency:get -Dartifact="${{ env.GROUP_ID }}:$module:$VERSION" -B >/dev/null 2>&1; then
echo "✅ $module available"
break
fi
if [[ $i -eq $WAIT_ITERATIONS ]]; then
echo "❌ $module not available after waiting"
exit 1
fi
sleep 120
done
done
echo "✅ All Framework modules available"
- name: Verify deployment
run: |
set -e
VERSION=${{ steps.version.outputs.version }}
modules=("java-reporter-core" "java-reporter-junit" "java-reporter-testng" "java-reporter-cucumber" "java-reporter-karate" "testomat-allure-adapter")
echo "🔍 Verifying deployment..."
echo "Waiting 5 minutes for Maven Central propagation..."
sleep 300
failed_modules=()
for module in "${modules[@]}"; do
echo "Verifying $module..."
if timeout 120 mvn dependency:get -Dartifact="${{ env.GROUP_ID }}:$module:$VERSION" -B >/dev/null 2>&1; then
echo "✅ $module verified"
else
echo "⚠️ $module verification failed"
failed_modules+=("$module")
fi
done
if [[ ${#failed_modules[@]} -gt 0 ]]; then
echo "⚠️ Verification failed for: ${failed_modules[*]}"
echo "This might be due to Maven Central propagation delays."
else
echo "✅ All modules verified successfully"
fi
- name: Cleanup GPG
if: always()
run: |
if command -v gpg >/dev/null 2>&1; then
KEY_IDS=$(gpg --list-secret-keys --keyid-format LONG 2>/dev/null | grep sec | awk '{print $2}' | cut -d'/' -f2 2>/dev/null || true)
if [[ -n "$KEY_IDS" ]]; then
for key_id in $KEY_IDS; do
gpg --batch --yes --delete-secret-keys "$key_id" 2>/dev/null || true
done
echo "✅ GPG keys cleaned up"
fi
fi
- name: Release notification
if: always()
run: |
if [[ "${{ job.status }}" == "success" ]]; then
echo "🎉 Release v${{ steps.version.outputs.version }} completed successfully!"
echo ""
echo "Deployed modules with correct dependency chain:"
echo "• Core v${{ steps.version.outputs.version }}"
echo "• Framework modules v${{ steps.version.outputs.version }} (depend on Core v${{ steps.version.outputs.version }})"
else
echo "❌ Release v${{ steps.version.outputs.version }} failed!"
echo "Check the workflow logs for detailed error information."
fi