Skip to content

Add HDF5 Java bindings to Maven #91

Add HDF5 Java bindings to Maven

Add HDF5 Java bindings to Maven #91

Workflow file for this run

name: Maven Staging Repository Test
# Triggers on pull requests that modify Maven-related files
on:
pull_request:
branches: [ develop, main ]
paths:
- 'java/src/hdf/hdf5lib/**'
- 'HDF5Examples/JAVA/**'
- '.github/workflows/maven-*.yml'
- '.github/workflows/java-examples-*.yml'
- 'CMakePresets.json'
- '**/CMakeLists.txt'
- 'java/src/hdf/hdf5lib/pom.xml.in'
- 'HDF5Examples/JAVA/pom-examples.xml.in'
workflow_call:
inputs:
test_maven_deployment:
description: 'Test Maven deployment to staging'
type: boolean
required: false
default: true
use_snapshot_version:
description: 'Use snapshot version (-SNAPSHOT suffix)'
type: boolean
required: false
default: true
platforms:
description: 'Build platforms for Maven artifacts'
type: string
required: false
default: 'all-platforms'
workflow_dispatch:
inputs:
test_maven_deployment:
description: 'Test Maven deployment to staging'
type: boolean
required: false
default: true
use_snapshot_version:
description: 'Use snapshot version (-SNAPSHOT suffix)'
type: boolean
required: false
default: true
platforms:
description: 'Build platforms for Maven artifacts'
type: choice
required: false
default: 'all-platforms'
options:
- 'linux-only'
- 'linux-windows'
- 'linux-macos'
- 'all-platforms'
permissions:
contents: read
packages: write
pull-requests: write
jobs:
detect-changes:
name: Detect Maven-related Changes
runs-on: ubuntu-latest
outputs:
maven-changes: ${{ steps.changes.outputs.maven }}
should-test: ${{ steps.should-test.outputs.result }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect changes in Maven-related files
id: changes
run: |
# Check if this is a manual trigger
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
echo "maven=true" >> $GITHUB_OUTPUT
echo "Manual workflow dispatch - Maven testing enabled"
exit 0
fi
# For pull requests, check changed files
git fetch origin ${{ github.base_ref }}
MAVEN_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E "(java/src/hdf/hdf5lib/|HDF5Examples/JAVA/|maven|pom\.xml|CMakePresets\.json)" || true)
if [ -n "$MAVEN_FILES" ]; then
echo "maven=true" >> $GITHUB_OUTPUT
echo "Maven-related changes detected:"
echo "$MAVEN_FILES"
else
echo "maven=false" >> $GITHUB_OUTPUT
echo "No Maven-related changes detected"
fi
- name: Determine if Maven testing should run
id: should-test
run: |
if [ "${{ steps.changes.outputs.maven }}" == "true" ] || [ "${{ inputs.test_maven_deployment }}" == "true" ]; then
echo "result=true" >> $GITHUB_OUTPUT
echo "Maven testing will be performed"
else
echo "result=false" >> $GITHUB_OUTPUT
echo "Maven testing will be skipped"
fi
build-maven-artifacts:
name: Build Maven Test Artifacts
needs: detect-changes
if: ${{ needs.detect-changes.outputs.should-test == 'true' }}
runs-on: ubuntu-latest
outputs:
artifacts-created: ${{ steps.artifacts-check.outputs.created }}
version-info: ${{ steps.version-info.outputs.version }}
steps:
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install ninja-build doxygen
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Checkout code
uses: actions/checkout@v4
- name: Set file base name
id: set-file-base
shell: bash
run: |
FILE_NAME_BASE="hdf5-develop-$(date '+%Y%m%d')"
echo "FILE_BASE=$FILE_NAME_BASE" >> $GITHUB_OUTPUT
echo "SOURCE_BASE=hdfsrc" >> $GITHUB_OUTPUT
- name: Create source tarball
shell: bash
run: |
mkdir -p ${{ runner.workspace }}/source
cd ${{ runner.workspace }}/source
# Create a simplified source package for testing
tar -czf ${{ steps.set-file-base.outputs.FILE_BASE }}.tar.gz -C ${{ github.workspace }} --exclude='.git' .
- name: Extract source for build
id: extract
shell: bash
run: |
cd ${{ runner.workspace }}
BUILD_DIR="hdf5"
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
tar -xzf ${{ runner.workspace }}/source/${{ steps.set-file-base.outputs.FILE_BASE }}.tar.gz -C "$BUILD_DIR/"
# Move extracted contents if they're in a subdirectory
if [ -d "$BUILD_DIR${{ github.workspace }}" ]; then
mv "$BUILD_DIR${{ github.workspace }}"/* "$BUILD_DIR/" || true
rmdir "$BUILD_DIR${{ github.workspace }}" || true
fi
echo "BUILD_DIR=$BUILD_DIR" >> $GITHUB_OUTPUT
- name: Set preset name
id: set-preset
shell: bash
run: |
# Determine preset based on snapshot setting (using minimal presets for Linux/GCC)
if [ "${{ inputs.use_snapshot_version }}" == "true" ] || [ "${{ github.event_name }}" == "pull_request" ]; then
echo "Building with minimal Maven snapshot preset for GNUC"
PRESET_NAME="ci-MinShar-GNUC-Maven-Snapshot"
else
echo "Building with minimal Maven release preset for GNUC"
PRESET_NAME="ci-MinShar-GNUC-Maven"
fi
echo "preset=$PRESET_NAME" >> $GITHUB_OUTPUT
echo "Using preset: $PRESET_NAME"
- name: Build HDF5 with Maven support
id: buildhdf5
shell: bash
run: |
cd ${{ runner.workspace }}/${{ steps.extract.outputs.BUILD_DIR }}
cmake --workflow --preset="${{ steps.set-preset.outputs.preset }}" --fresh
- name: Extract version information
id: version-info
shell: bash
run: |
# Find the generated POM file across all possible locations
BUILD_ROOT="${{ runner.workspace }}/build/${{ steps.set-preset.outputs.preset }}"
echo "Looking for POM file in: $BUILD_ROOT"
# Try multiple search patterns for cross-platform compatibility
POM_FILE=""
# Search patterns in order of preference
if [ -z "$POM_FILE" ]; then
POM_FILE=$(find "$BUILD_ROOT" -name "pom.xml" -path "*/java/*" | head -1)
fi
if [ -z "$POM_FILE" ]; then
POM_FILE=$(find "$BUILD_ROOT" -name "pom.xml" | head -1)
fi
# Try Maven artifacts directory if build structure differs
if [ -z "$POM_FILE" ] && [ -d "${{ runner.workspace }}/maven-artifacts" ]; then
POM_FILE=$(find "${{ runner.workspace }}/maven-artifacts" -name "pom.xml" | head -1)
fi
if [ -n "$POM_FILE" ] && [ -f "$POM_FILE" ]; then
# Extract version using robust pattern that works across platforms
VERSION=$(grep -o '<version>[^<]*</version>' "$POM_FILE" | head -1 | sed 's/<[^>]*>//g' | tr -d '\r\n')
# Validate version format
if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "✓ Detected version: $VERSION"
echo "✓ POM file: $POM_FILE"
else
echo "version=unknown" >> $GITHUB_OUTPUT
echo "❌ Invalid version format detected: $VERSION"
exit 1
fi
else
echo "version=unknown" >> $GITHUB_OUTPUT
echo "❌ Could not find POM file"
echo "Available files in build root:"
find "$BUILD_ROOT" -name "*.xml" -o -name "pom*" 2>/dev/null | head -10 || echo "No XML files found"
exit 1
fi
- name: Collect Maven artifacts
shell: bash
run: |
echo "Collecting Maven artifacts for testing..."
mkdir -p ${{ runner.workspace }}/maven-artifacts
BUILD_ROOT="${{ runner.workspace }}/build/${{ steps.set-preset.outputs.preset }}"
echo "Looking for Maven artifacts in build root: $BUILD_ROOT"
if [ ! -d "$BUILD_ROOT" ]; then
echo "ERROR: Build root directory does not exist: $BUILD_ROOT"
exit 1
fi
# Debug: Show what's in the build directory
echo "Build directory contents:"
find "$BUILD_ROOT" -maxdepth 3 -type d 2>/dev/null | head -20 || echo "Directory listing completed"
# Find build directory (try multiple patterns)
BUILD_DIR=$(find "$BUILD_ROOT" -name "*Maven*" -type d | head -1)
if [ -z "$BUILD_DIR" ]; then
# Try looking for java directory as fallback (more specific patterns)
BUILD_DIR=$(find "$BUILD_ROOT" -path "*/java/*" -type d | head -1)
if [ -z "$BUILD_DIR" ]; then
BUILD_DIR=$(find "$BUILD_ROOT" -name "java" -type d | head -1)
fi
fi
if [ -z "$BUILD_DIR" ]; then
# Try looking for any directory with JAR files
JAR_FILE=$(find "$BUILD_ROOT" -name "*.jar" -type f | head -1)
if [ -n "$JAR_FILE" ]; then
BUILD_DIR=$(dirname "$JAR_FILE")
echo "Found JAR file in: $BUILD_DIR"
fi
fi
if [ -z "$BUILD_DIR" ]; then
# Last resort: look for the build directory itself if it contains artifacts
if find "$BUILD_ROOT" -name "*.jar" -o -name "pom.xml" | grep -q .; then
BUILD_DIR="$BUILD_ROOT"
echo "Using build root as artifacts directory"
fi
fi
if [ -z "$BUILD_DIR" ]; then
echo "ERROR: Could not find Maven build directory with any of the patterns"
echo "Available directories:"
find "$BUILD_ROOT" -maxdepth 2 -type d
exit 1
fi
echo "Looking for artifacts in: $BUILD_DIR"
# Debug: Show all JAR files in build directory
echo "All JAR files in build directory:"
find "$BUILD_DIR" -name "*.jar" -type f | head -20
# Debug: Show specifically what we're looking for
echo "SLF4J JAR files in build directory:"
find "$BUILD_DIR" -name "*slf4j*.jar" -type f
# Copy JAR files (excluding test and H5Ex_ example JARs)
find "$BUILD_DIR" -name "*.jar" -not -name "*test*" -not -name "*H5Ex_*" -exec cp {} ${{ runner.workspace }}/maven-artifacts/ \;
# Also look for Maven dependencies in common locations
echo "Looking for Maven dependencies in additional locations..."
# Check if there's a Maven repository in the build area
if [ -d "$BUILD_ROOT" ]; then
find "$BUILD_ROOT" -name "*slf4j*.jar" -type f -exec cp {} ${{ runner.workspace }}/maven-artifacts/ \;
fi
# Check common Maven local repository locations
MAVEN_REPO_PATHS=(
"$HOME/.m2/repository"
"$BUILD_ROOT/.m2/repository"
"${{ runner.workspace }}/.m2/repository"
)
for repo_path in "${MAVEN_REPO_PATHS[@]}"; do
if [ -d "$repo_path" ]; then
echo "Checking Maven repository: $repo_path"
find "$repo_path" -name "slf4j-api*.jar" -o -name "slf4j-simple*.jar" | head -2 | while read jar_file; do
if [ -f "$jar_file" ]; then
echo "Found dependency: $jar_file"
cp "$jar_file" ${{ runner.workspace }}/maven-artifacts/
fi
done
fi
done
# Copy POM files
find "$BUILD_DIR" -name "pom.xml" -exec cp {} ${{ runner.workspace }}/maven-artifacts/ \;
# List collected artifacts
echo "Collected Maven artifacts:"
ls -la ${{ runner.workspace }}/maven-artifacts/
- name: Validate artifacts
id: artifacts-check
shell: bash
run: |
ARTIFACT_COUNT=$(find ${{ runner.workspace }}/maven-artifacts -name "*.jar" | wc -l)
POM_COUNT=$(find ${{ runner.workspace }}/maven-artifacts -name "pom.xml" | wc -l)
echo "Found $ARTIFACT_COUNT JAR files and $POM_COUNT POM files"
if [ $ARTIFACT_COUNT -gt 0 ] && [ $POM_COUNT -gt 0 ]; then
echo "created=true" >> $GITHUB_OUTPUT
echo "✅ Artifacts successfully created"
else
echo "created=false" >> $GITHUB_OUTPUT
echo "❌ Artifact creation failed"
exit 1
fi
- name: Run validation script
shell: bash
run: |
if [ -f .github/scripts/validate-maven-artifacts.sh ]; then
echo "Running Maven artifact validation..."
.github/scripts/validate-maven-artifacts.sh ${{ runner.workspace }}/maven-artifacts
else
echo "Validation script not found - skipping validation"
fi
- name: Upload Maven artifacts
uses: actions/upload-artifact@v4
with:
name: maven-staging-artifacts-linux-x86_64
path: ${{ runner.workspace }}/maven-artifacts
retention-days: 7
build-maven-artifacts-windows:
name: Build Maven Test Artifacts (Windows)
needs: detect-changes
if: ${{ needs.detect-changes.outputs.should-test == 'true' && (inputs.platforms == '' || contains(inputs.platforms, 'windows') || inputs.platforms == 'all-platforms') }}
runs-on: windows-latest
outputs:
artifacts-created: ${{ steps.artifacts-check.outputs.created }}
version-info: ${{ steps.version-info.outputs.version }}
steps:
- name: Install Dependencies
run: |
choco install ninja
choco install doxygen.install
- name: Enable Developer Command Prompt
uses: ilammy/[email protected]
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Checkout code
uses: actions/checkout@v4
- name: Set file base name
id: set-file-base
shell: pwsh
run: |
$FILE_NAME_BASE = "hdf5-develop-$(Get-Date -Format 'yyyyMMdd')"
echo "FILE_BASE=$FILE_NAME_BASE" >> $env:GITHUB_OUTPUT
echo "SOURCE_BASE=hdfsrc" >> $env:GITHUB_OUTPUT
- name: Create source tarball
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path "${{ runner.workspace }}/source"
Set-Location "${{ runner.workspace }}/source"
# Create a simplified source package for testing (Windows uses tar via Git Bash)
& tar -czf "${{ steps.set-file-base.outputs.FILE_BASE }}.tar.gz" -C "${{ github.workspace }}" --exclude=".git" .
- name: Extract source for build
id: extract
shell: pwsh
run: |
Set-Location "${{ runner.workspace }}"
# Use unique directory name to avoid file locking issues
$BUILD_DIR = "hdf5-build-$(Get-Date -Format 'HHmmss')"
Write-Host "Using build directory: $BUILD_DIR"
New-Item -ItemType Directory -Force -Path "$BUILD_DIR"
# Use tar to extract (available via Git Bash on Windows runners)
& tar -xzf "${{ runner.workspace }}/source/${{ steps.set-file-base.outputs.FILE_BASE }}.tar.gz" -C "$BUILD_DIR/"
# Set output for later steps to use
echo "BUILD_DIR=$BUILD_DIR" >> $env:GITHUB_OUTPUT
- name: Set preset name
id: set-preset
shell: bash
run: |
# Determine preset based on snapshot setting (using minimal presets for Windows/MSVC)
if [ "${{ inputs.use_snapshot_version }}" == "true" ] || [ "${{ github.event_name }}" == "pull_request" ]; then
echo "Building with minimal Maven snapshot preset for MSVC"
PRESET_NAME="ci-MinShar-MSVC-Maven-Snapshot"
else
echo "Building with minimal Maven release preset for MSVC"
PRESET_NAME="ci-MinShar-MSVC-Maven"
fi
echo "preset=$PRESET_NAME" >> $GITHUB_OUTPUT
echo "Using preset: $PRESET_NAME"
- name: Build HDF5 with Maven support
id: buildhdf5
shell: pwsh
run: |
Set-Location "${{ runner.workspace }}/${{ steps.extract.outputs.BUILD_DIR }}"
cmake --workflow --preset="${{ steps.set-preset.outputs.preset }}" --fresh
- name: Extract version information
id: version-info
shell: bash
run: |
# Find the generated POM file across all possible locations
BUILD_ROOT="${{ runner.workspace }}/build/${{ steps.set-preset.outputs.preset }}"
echo "Looking for POM file in: $BUILD_ROOT"
# Try multiple search patterns for cross-platform compatibility
POM_FILE=""
# Search patterns in order of preference
if [ -z "$POM_FILE" ]; then
POM_FILE=$(find "$BUILD_ROOT" -name "pom.xml" -path "*/java/*" | head -1)
fi
if [ -z "$POM_FILE" ]; then
POM_FILE=$(find "$BUILD_ROOT" -name "pom.xml" | head -1)
fi
# Try Maven artifacts directory if build structure differs
if [ -z "$POM_FILE" ] && [ -d "${{ runner.workspace }}/maven-artifacts" ]; then
POM_FILE=$(find "${{ runner.workspace }}/maven-artifacts" -name "pom.xml" | head -1)
fi
if [ -n "$POM_FILE" ] && [ -f "$POM_FILE" ]; then
# Extract version using robust pattern that works across platforms
VERSION=$(grep -o '<version>[^<]*</version>' "$POM_FILE" | head -1 | sed 's/<[^>]*>//g' | tr -d '\r\n')
# Validate version format
if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "✓ Detected version: $VERSION"
echo "✓ POM file: $POM_FILE"
else
echo "version=unknown" >> $GITHUB_OUTPUT
echo "❌ Invalid version format detected: $VERSION"
exit 1
fi
else
echo "version=unknown" >> $GITHUB_OUTPUT
echo "❌ Could not find POM file"
echo "Available files in build root:"
find "$BUILD_ROOT" -name "*.xml" -o -name "pom*" 2>/dev/null | head -10 || echo "No XML files found"
exit 1
fi
- name: Collect Maven artifacts
shell: pwsh
run: |
Write-Host "Collecting Maven artifacts for testing..."
New-Item -ItemType Directory -Force -Path "${{ runner.workspace }}/maven-artifacts"
# Debug: Show what's in the build directory
$BUILD_ROOT = "${{ runner.workspace }}/build/${{ steps.set-preset.outputs.preset }}"
Write-Host "Looking for Maven artifacts in build root: $BUILD_ROOT"
if (Test-Path $BUILD_ROOT) {
Write-Host "Build directory contents:"
Get-ChildItem -Path $BUILD_ROOT -Recurse -Directory | ForEach-Object { Write-Host " DIR: $($_.FullName)" }
# Find Maven build directory (try multiple patterns)
$BUILD_DIR = Get-ChildItem -Path $BUILD_ROOT -Directory -Filter "*Maven*" | Select-Object -First 1
if (-not $BUILD_DIR) {
# Try looking for java directory as fallback (more specific patterns)
$BUILD_DIR = Get-ChildItem -Path $BUILD_ROOT -Recurse -Directory | Where-Object { $_.FullName -match "java" } | Select-Object -First 1
}
if (-not $BUILD_DIR) {
# Try looking for any directory with JAR files
$JAR_FILES = Get-ChildItem -Path $BUILD_ROOT -Recurse -Filter "*.jar"
if ($JAR_FILES) {
$BUILD_DIR = $JAR_FILES[0].Directory
Write-Host "Found JAR files in: $($BUILD_DIR.FullName)"
}
}
if (-not $BUILD_DIR) {
# Last resort: use build root if it contains artifacts
$HAS_ARTIFACTS = (Get-ChildItem -Path $BUILD_ROOT -Recurse -Filter "*.jar").Count -gt 0 -or (Get-ChildItem -Path $BUILD_ROOT -Recurse -Filter "pom.xml").Count -gt 0
if ($HAS_ARTIFACTS) {
$BUILD_DIR = Get-Item $BUILD_ROOT
Write-Host "Using build root as artifacts directory"
}
}
} else {
Write-Host "ERROR: Build root directory does not exist: $BUILD_ROOT"
exit 1
}
if (-not $BUILD_DIR) {
Write-Host "ERROR: Could not find Maven build directory with any of the patterns"
Write-Host "Available directories:"
Get-ChildItem -Path $BUILD_ROOT -Directory | ForEach-Object { Write-Host " $($_.Name)" }
exit 1
}
Write-Host "Looking for artifacts in: $($BUILD_DIR.FullName)"
# Copy JAR files (excluding test and H5Ex_ example JARs)
Get-ChildItem -Path $BUILD_DIR.FullName -Filter "*.jar" -Recurse | Where-Object {
$_.Name -notmatch "test" -and $_.Name -notmatch "H5Ex_"
} | ForEach-Object {
Copy-Item $_.FullName "${{ runner.workspace }}/maven-artifacts/"
}
# Copy POM files
Get-ChildItem -Path $BUILD_DIR.FullName -Filter "pom.xml" -Recurse | ForEach-Object {
Copy-Item $_.FullName "${{ runner.workspace }}/maven-artifacts/"
}
# List collected artifacts
Write-Host "Collected Maven artifacts:"
Get-ChildItem "${{ runner.workspace }}/maven-artifacts/" | ForEach-Object { Write-Host $_.Name }
- name: Validate artifacts
id: artifacts-check
shell: pwsh
run: |
$ARTIFACT_COUNT = (Get-ChildItem -Path "${{ runner.workspace }}/maven-artifacts" -Filter "*.jar").Count
$POM_COUNT = (Get-ChildItem -Path "${{ runner.workspace }}/maven-artifacts" -Filter "pom.xml").Count
Write-Host "Found $ARTIFACT_COUNT JAR files and $POM_COUNT POM files"
if ($ARTIFACT_COUNT -gt 0 -and $POM_COUNT -gt 0) {
echo "created=true" >> $env:GITHUB_OUTPUT
Write-Host "✅ Artifacts successfully created"
} else {
echo "created=false" >> $env:GITHUB_OUTPUT
Write-Host "❌ Artifact creation failed"
exit 1
}
- name: Run validation script
shell: bash
run: |
# Use GITHUB_WORKSPACE environment variable which is more reliable on Windows
echo "GitHub workspace: $GITHUB_WORKSPACE"
echo "Runner workspace: ${{ runner.workspace }}"
if [ -f "$GITHUB_WORKSPACE/.github/scripts/validate-maven-artifacts.sh" ]; then
echo "Running Maven artifact validation..."
echo "Maven artifacts directory contents:"
ls -la "${{ runner.workspace }}/maven-artifacts/" || echo "maven-artifacts directory not found"
# Use the script with full path and convert runner.workspace for Windows
ARTIFACTS_DIR="${{ runner.workspace }}/maven-artifacts"
# Convert any Windows backslashes to forward slashes for bash
ARTIFACTS_DIR=$(echo "$ARTIFACTS_DIR" | tr '\\' '/')
echo "Artifacts directory: $ARTIFACTS_DIR"
"$GITHUB_WORKSPACE/.github/scripts/validate-maven-artifacts.sh" "$ARTIFACTS_DIR"
else
echo "Validation script not found at $GITHUB_WORKSPACE/.github/scripts/validate-maven-artifacts.sh"
echo "Skipping validation"
fi
- name: Upload Maven artifacts
uses: actions/upload-artifact@v4
with:
name: maven-staging-artifacts-windows-x86_64
path: ${{ runner.workspace }}/maven-artifacts
retention-days: 7
build-maven-artifacts-macos-x86_64:
name: Build Maven Test Artifacts (macOS x86_64)
needs: detect-changes
if: ${{ needs.detect-changes.outputs.should-test == 'true' && (inputs.platforms == '' || contains(inputs.platforms, 'macos') || inputs.platforms == 'all-platforms') }}
runs-on: macos-13 # Intel-based macOS runner
outputs:
artifacts-created: ${{ steps.artifacts-check.outputs.created }}
version-info: ${{ steps.version-info.outputs.version }}
steps:
- name: Install Dependencies
run: |
brew install ninja
brew install doxygen
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Checkout code
uses: actions/checkout@v4
- name: Set file base name
id: set-file-base
shell: bash
run: |
FILE_NAME_BASE="hdf5-develop-$(date '+%Y%m%d')"
echo "FILE_BASE=$FILE_NAME_BASE" >> $GITHUB_OUTPUT
echo "SOURCE_BASE=hdfsrc" >> $GITHUB_OUTPUT
- name: Create source tarball
shell: bash
run: |
mkdir -p ${{ runner.workspace }}/source
cd ${{ runner.workspace }}/source
# Create a simplified source package for testing
tar -czf ${{ steps.set-file-base.outputs.FILE_BASE }}.tar.gz -C ${{ github.workspace }} --exclude='.git' .
- name: Extract source for build
id: extract
shell: bash
run: |
cd ${{ runner.workspace }}
BUILD_DIR="hdf5"
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
tar -xzf ${{ runner.workspace }}/source/${{ steps.set-file-base.outputs.FILE_BASE }}.tar.gz -C "$BUILD_DIR/"
# Move extracted contents if they're in a subdirectory
if [ -d "$BUILD_DIR${{ github.workspace }}" ]; then
mv "$BUILD_DIR${{ github.workspace }}"/* "$BUILD_DIR/" || true
rmdir "$BUILD_DIR${{ github.workspace }}" || true
fi
echo "BUILD_DIR=$BUILD_DIR" >> $GITHUB_OUTPUT
- name: Set preset name
id: set-preset
shell: bash
run: |
# Determine preset based on snapshot setting (using minimal presets for macOS/Clang)
if [ "${{ inputs.use_snapshot_version }}" == "true" ] || [ "${{ github.event_name }}" == "pull_request" ]; then
echo "Building with minimal Maven snapshot preset for Clang"
PRESET_NAME="ci-MinShar-Clang-Maven-Snapshot"
else
echo "Building with minimal Maven release preset for Clang"
PRESET_NAME="ci-MinShar-Clang-Maven"
fi
echo "preset=$PRESET_NAME" >> $GITHUB_OUTPUT
echo "Using preset: $PRESET_NAME"
- name: Build HDF5 with Maven support
id: buildhdf5
shell: bash
run: |
cd ${{ runner.workspace }}/${{ steps.extract.outputs.BUILD_DIR }}
cmake --workflow --preset="${{ steps.set-preset.outputs.preset }}" --fresh
- name: Extract version information
id: version-info
shell: bash
run: |
# Find the generated POM file across all possible locations
BUILD_ROOT="${{ runner.workspace }}/build/${{ steps.set-preset.outputs.preset }}"
echo "Looking for POM file in: $BUILD_ROOT"
# Try multiple search patterns for cross-platform compatibility
POM_FILE=""
# Search patterns in order of preference
if [ -z "$POM_FILE" ]; then
POM_FILE=$(find "$BUILD_ROOT" -name "pom.xml" -path "*/java/*" | head -1)
fi
if [ -z "$POM_FILE" ]; then
POM_FILE=$(find "$BUILD_ROOT" -name "pom.xml" | head -1)
fi
# Try Maven artifacts directory if build structure differs
if [ -z "$POM_FILE" ] && [ -d "${{ runner.workspace }}/maven-artifacts" ]; then
POM_FILE=$(find "${{ runner.workspace }}/maven-artifacts" -name "pom.xml" | head -1)
fi
if [ -n "$POM_FILE" ] && [ -f "$POM_FILE" ]; then
# Extract version using robust pattern that works across platforms
VERSION=$(grep -o '<version>[^<]*</version>' "$POM_FILE" | head -1 | sed 's/<[^>]*>//g' | tr -d '\r\n')
# Validate version format
if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "✓ Detected version: $VERSION"
echo "✓ POM file: $POM_FILE"
else
echo "version=unknown" >> $GITHUB_OUTPUT
echo "❌ Invalid version format detected: $VERSION"
exit 1
fi
else
echo "version=unknown" >> $GITHUB_OUTPUT
echo "❌ Could not find POM file"
echo "Available files in build root:"
find "$BUILD_ROOT" -name "*.xml" -o -name "pom*" 2>/dev/null | head -10 || echo "No XML files found"
exit 1
fi
- name: Collect Maven artifacts
shell: bash
run: |
echo "Collecting Maven artifacts for testing..."
mkdir -p ${{ runner.workspace }}/maven-artifacts
BUILD_ROOT="${{ runner.workspace }}/build/${{ steps.set-preset.outputs.preset }}"
echo "Looking for Maven artifacts in build root: $BUILD_ROOT"
if [ ! -d "$BUILD_ROOT" ]; then
echo "ERROR: Build root directory does not exist: $BUILD_ROOT"
exit 1
fi
# Debug: Show what's in the build directory
echo "Build directory contents:"
find "$BUILD_ROOT" -maxdepth 3 -type d 2>/dev/null | head -20 || echo "Directory listing completed"
# Find build directory (try multiple patterns)
BUILD_DIR=$(find "$BUILD_ROOT" -name "*Maven*" -type d | head -1)
if [ -z "$BUILD_DIR" ]; then
# Try looking for java directory as fallback (more specific patterns)
BUILD_DIR=$(find "$BUILD_ROOT" -path "*/java/*" -type d | head -1)
if [ -z "$BUILD_DIR" ]; then
BUILD_DIR=$(find "$BUILD_ROOT" -name "java" -type d | head -1)
fi
fi
if [ -z "$BUILD_DIR" ]; then
# Try looking for any directory with JAR files
JAR_FILE=$(find "$BUILD_ROOT" -name "*.jar" -type f | head -1)
if [ -n "$JAR_FILE" ]; then
BUILD_DIR=$(dirname "$JAR_FILE")
echo "Found JAR file in: $BUILD_DIR"
fi
fi
if [ -z "$BUILD_DIR" ]; then
# Last resort: look for the build directory itself if it contains artifacts
if find "$BUILD_ROOT" -name "*.jar" -o -name "pom.xml" | grep -q .; then
BUILD_DIR="$BUILD_ROOT"
echo "Using build root as artifacts directory"
fi
fi
if [ -z "$BUILD_DIR" ]; then
echo "ERROR: Could not find Maven build directory with any of the patterns"
echo "Available directories:"
find "$BUILD_ROOT" -maxdepth 2 -type d
exit 1
fi
echo "Looking for artifacts in: $BUILD_DIR"
# Debug: Show all JAR files in build directory
echo "All JAR files in build directory:"
find "$BUILD_DIR" -name "*.jar" -type f | head -20
# Debug: Show specifically what we're looking for
echo "SLF4J JAR files in build directory:"
find "$BUILD_DIR" -name "*slf4j*.jar" -type f
# Copy JAR files (excluding test and H5Ex_ example JARs)
find "$BUILD_DIR" -name "*.jar" -not -name "*test*" -not -name "*H5Ex_*" -exec cp {} ${{ runner.workspace }}/maven-artifacts/ \;
# Also look for Maven dependencies in common locations
echo "Looking for Maven dependencies in additional locations..."
# Check if there's a Maven repository in the build area
if [ -d "$BUILD_ROOT" ]; then
find "$BUILD_ROOT" -name "*slf4j*.jar" -type f -exec cp {} ${{ runner.workspace }}/maven-artifacts/ \;
fi
# Check common Maven local repository locations
MAVEN_REPO_PATHS=(
"$HOME/.m2/repository"
"$BUILD_ROOT/.m2/repository"
"${{ runner.workspace }}/.m2/repository"
)
for repo_path in "${MAVEN_REPO_PATHS[@]}"; do
if [ -d "$repo_path" ]; then
echo "Checking Maven repository: $repo_path"
find "$repo_path" -name "slf4j-api*.jar" -o -name "slf4j-simple*.jar" | head -2 | while read jar_file; do
if [ -f "$jar_file" ]; then
echo "Found dependency: $jar_file"
cp "$jar_file" ${{ runner.workspace }}/maven-artifacts/
fi
done
fi
done
# Copy POM files
find "$BUILD_DIR" -name "pom.xml" -exec cp {} ${{ runner.workspace }}/maven-artifacts/ \;
# List collected artifacts
echo "Collected Maven artifacts:"
ls -la ${{ runner.workspace }}/maven-artifacts/
- name: Validate artifacts
id: artifacts-check
shell: bash
run: |
ARTIFACT_COUNT=$(find ${{ runner.workspace }}/maven-artifacts -name "*.jar" | wc -l)
POM_COUNT=$(find ${{ runner.workspace }}/maven-artifacts -name "pom.xml" | wc -l)
echo "Found $ARTIFACT_COUNT JAR files and $POM_COUNT POM files"
if [ $ARTIFACT_COUNT -gt 0 ] && [ $POM_COUNT -gt 0 ]; then
echo "created=true" >> $GITHUB_OUTPUT
echo "✅ Artifacts successfully created"
else
echo "created=false" >> $GITHUB_OUTPUT
echo "❌ Artifact creation failed"
exit 1
fi
- name: Run validation script
shell: bash
run: |
if [ -f .github/scripts/validate-maven-artifacts.sh ]; then
echo "Running Maven artifact validation..."
.github/scripts/validate-maven-artifacts.sh ${{ runner.workspace }}/maven-artifacts
else
echo "Validation script not found - skipping validation"
fi
- name: Upload Maven artifacts
uses: actions/upload-artifact@v4
with:
name: maven-staging-artifacts-macos-x86_64
path: ${{ runner.workspace }}/maven-artifacts
retention-days: 7
build-maven-artifacts-macos-aarch64:
name: Build Maven Test Artifacts (macOS aarch64)
needs: detect-changes
if: ${{ needs.detect-changes.outputs.should-test == 'true' && (inputs.platforms == '' || contains(inputs.platforms, 'macos') || inputs.platforms == 'all-platforms') }}
runs-on: macos-latest # ARM-based macOS runner
outputs:
artifacts-created: ${{ steps.artifacts-check.outputs.created }}
version-info: ${{ steps.version-info.outputs.version }}
steps:
- name: Install Dependencies
run: |
brew install ninja
brew install doxygen
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Checkout code
uses: actions/checkout@v4
- name: Set file base name
id: set-file-base
shell: bash
run: |
FILE_NAME_BASE="hdf5-develop-$(date '+%Y%m%d')"
echo "FILE_BASE=$FILE_NAME_BASE" >> $GITHUB_OUTPUT
echo "SOURCE_BASE=hdfsrc" >> $GITHUB_OUTPUT
- name: Create source tarball
shell: bash
run: |
mkdir -p ${{ runner.workspace }}/source
cd ${{ runner.workspace }}/source
# Create a simplified source package for testing
tar -czf ${{ steps.set-file-base.outputs.FILE_BASE }}.tar.gz -C ${{ github.workspace }} --exclude='.git' .
- name: Extract source for build
id: extract
shell: bash
run: |
cd ${{ runner.workspace }}
BUILD_DIR="hdf5"
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
tar -xzf ${{ runner.workspace }}/source/${{ steps.set-file-base.outputs.FILE_BASE }}.tar.gz -C "$BUILD_DIR/"
# Move extracted contents if they're in a subdirectory
if [ -d "$BUILD_DIR${{ github.workspace }}" ]; then
mv "$BUILD_DIR${{ github.workspace }}"/* "$BUILD_DIR/" || true
rmdir "$BUILD_DIR${{ github.workspace }}" || true
fi
echo "BUILD_DIR=$BUILD_DIR" >> $GITHUB_OUTPUT
- name: Set preset name
id: set-preset
shell: bash
run: |
# Determine preset based on snapshot setting (using minimal presets for macOS/Clang)
if [ "${{ inputs.use_snapshot_version }}" == "true" ] || [ "${{ github.event_name }}" == "pull_request" ]; then
echo "Building with minimal Maven snapshot preset for Clang"
PRESET_NAME="ci-MinShar-Clang-Maven-Snapshot"
else
echo "Building with minimal Maven release preset for Clang"
PRESET_NAME="ci-MinShar-Clang-Maven"
fi
echo "preset=$PRESET_NAME" >> $GITHUB_OUTPUT
echo "Using preset: $PRESET_NAME"
- name: Build HDF5 with Maven support
id: buildhdf5
shell: bash
run: |
cd ${{ runner.workspace }}/${{ steps.extract.outputs.BUILD_DIR }}
cmake --workflow --preset="${{ steps.set-preset.outputs.preset }}" --fresh
- name: Extract version information
id: version-info
shell: bash
run: |
# Find the generated POM file across all possible locations
BUILD_ROOT="${{ runner.workspace }}/build/${{ steps.set-preset.outputs.preset }}"
echo "Looking for POM file in: $BUILD_ROOT"
# Try multiple search patterns for cross-platform compatibility
POM_FILE=""
# Search patterns in order of preference
if [ -z "$POM_FILE" ]; then
POM_FILE=$(find "$BUILD_ROOT" -name "pom.xml" -path "*/java/*" | head -1)
fi
if [ -z "$POM_FILE" ]; then
POM_FILE=$(find "$BUILD_ROOT" -name "pom.xml" | head -1)
fi
# Try Maven artifacts directory if build structure differs
if [ -z "$POM_FILE" ] && [ -d "${{ runner.workspace }}/maven-artifacts" ]; then
POM_FILE=$(find "${{ runner.workspace }}/maven-artifacts" -name "pom.xml" | head -1)
fi
if [ -n "$POM_FILE" ] && [ -f "$POM_FILE" ]; then
# Extract version using robust pattern that works across platforms
VERSION=$(grep -o '<version>[^<]*</version>' "$POM_FILE" | head -1 | sed 's/<[^>]*>//g' | tr -d '\r\n')
# Validate version format
if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "✓ Detected version: $VERSION"
echo "✓ POM file: $POM_FILE"
else
echo "version=unknown" >> $GITHUB_OUTPUT
echo "❌ Invalid version format detected: $VERSION"
exit 1
fi
else
echo "version=unknown" >> $GITHUB_OUTPUT
echo "❌ Could not find POM file"
echo "Available files in build root:"
find "$BUILD_ROOT" -name "*.xml" -o -name "pom*" 2>/dev/null | head -10 || echo "No XML files found"
exit 1
fi
- name: Collect Maven artifacts
shell: bash
run: |
echo "Collecting Maven artifacts for testing..."
mkdir -p ${{ runner.workspace }}/maven-artifacts
BUILD_ROOT="${{ runner.workspace }}/build/${{ steps.set-preset.outputs.preset }}"
echo "Looking for Maven artifacts in build root: $BUILD_ROOT"
if [ ! -d "$BUILD_ROOT" ]; then
echo "ERROR: Build root directory does not exist: $BUILD_ROOT"
exit 1
fi
# Debug: Show what's in the build directory
echo "Build directory contents:"
find "$BUILD_ROOT" -maxdepth 3 -type d 2>/dev/null | head -20 || echo "Directory listing completed"
# Find build directory (try multiple patterns)
BUILD_DIR=$(find "$BUILD_ROOT" -name "*Maven*" -type d | head -1)
if [ -z "$BUILD_DIR" ]; then
# Try looking for java directory as fallback (more specific patterns)
BUILD_DIR=$(find "$BUILD_ROOT" -path "*/java/*" -type d | head -1)
if [ -z "$BUILD_DIR" ]; then
BUILD_DIR=$(find "$BUILD_ROOT" -name "java" -type d | head -1)
fi
fi
if [ -z "$BUILD_DIR" ]; then
# Try looking for any directory with JAR files
JAR_FILE=$(find "$BUILD_ROOT" -name "*.jar" -type f | head -1)
if [ -n "$JAR_FILE" ]; then
BUILD_DIR=$(dirname "$JAR_FILE")
echo "Found JAR file in: $BUILD_DIR"
fi
fi
if [ -z "$BUILD_DIR" ]; then
# Last resort: look for the build directory itself if it contains artifacts
if find "$BUILD_ROOT" -name "*.jar" -o -name "pom.xml" | grep -q .; then
BUILD_DIR="$BUILD_ROOT"
echo "Using build root as artifacts directory"
fi
fi
if [ -z "$BUILD_DIR" ]; then
echo "ERROR: Could not find Maven build directory with any of the patterns"
echo "Available directories:"
find "$BUILD_ROOT" -maxdepth 2 -type d
exit 1
fi
echo "Looking for artifacts in: $BUILD_DIR"
# Debug: Show all JAR files in build directory
echo "All JAR files in build directory:"
find "$BUILD_DIR" -name "*.jar" -type f | head -20
# Debug: Show specifically what we're looking for
echo "SLF4J JAR files in build directory:"
find "$BUILD_DIR" -name "*slf4j*.jar" -type f
# Copy JAR files (excluding test and H5Ex_ example JARs)
find "$BUILD_DIR" -name "*.jar" -not -name "*test*" -not -name "*H5Ex_*" -exec cp {} ${{ runner.workspace }}/maven-artifacts/ \;
# Also look for Maven dependencies in common locations
echo "Looking for Maven dependencies in additional locations..."
# Check if there's a Maven repository in the build area
if [ -d "$BUILD_ROOT" ]; then
find "$BUILD_ROOT" -name "*slf4j*.jar" -type f -exec cp {} ${{ runner.workspace }}/maven-artifacts/ \;
fi
# Check common Maven local repository locations
MAVEN_REPO_PATHS=(
"$HOME/.m2/repository"
"$BUILD_ROOT/.m2/repository"
"${{ runner.workspace }}/.m2/repository"
)
for repo_path in "${MAVEN_REPO_PATHS[@]}"; do
if [ -d "$repo_path" ]; then
echo "Checking Maven repository: $repo_path"
find "$repo_path" -name "slf4j-api*.jar" -o -name "slf4j-simple*.jar" | head -2 | while read jar_file; do
if [ -f "$jar_file" ]; then
echo "Found dependency: $jar_file"
cp "$jar_file" ${{ runner.workspace }}/maven-artifacts/
fi
done
fi
done
# Copy POM files
find "$BUILD_DIR" -name "pom.xml" -exec cp {} ${{ runner.workspace }}/maven-artifacts/ \;
# List collected artifacts
echo "Collected Maven artifacts:"
ls -la ${{ runner.workspace }}/maven-artifacts/
- name: Validate artifacts
id: artifacts-check
shell: bash
run: |
ARTIFACT_COUNT=$(find ${{ runner.workspace }}/maven-artifacts -name "*.jar" | wc -l)
POM_COUNT=$(find ${{ runner.workspace }}/maven-artifacts -name "pom.xml" | wc -l)
echo "Found $ARTIFACT_COUNT JAR files and $POM_COUNT POM files"
if [ $ARTIFACT_COUNT -gt 0 ] && [ $POM_COUNT -gt 0 ]; then
echo "created=true" >> $GITHUB_OUTPUT
echo "✅ Artifacts successfully created"
else
echo "created=false" >> $GITHUB_OUTPUT
echo "❌ Artifact creation failed"
exit 1
fi
- name: Run validation script
shell: bash
run: |
if [ -f .github/scripts/validate-maven-artifacts.sh ]; then
echo "Running Maven artifact validation..."
.github/scripts/validate-maven-artifacts.sh ${{ runner.workspace }}/maven-artifacts
else
echo "Validation script not found - skipping validation"
fi
- name: Upload Maven artifacts
uses: actions/upload-artifact@v4
with:
name: maven-staging-artifacts-macos-aarch64
path: ${{ runner.workspace }}/maven-artifacts
retention-days: 7
test-maven-deployment:
name: Test Maven Deployment
runs-on: ubuntu-latest
needs: [detect-changes, build-maven-artifacts, build-maven-artifacts-windows, build-maven-artifacts-macos-x86_64, build-maven-artifacts-macos-aarch64]
if: ${{ always() && needs.detect-changes.outputs.should-test == 'true' && needs.build-maven-artifacts.outputs.artifacts-created == 'true' }}
steps:
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Download Maven artifacts (Linux)
uses: actions/download-artifact@v4
with:
name: maven-staging-artifacts-linux-x86_64
path: ./artifacts/linux
- name: Download Maven artifacts (Windows)
if: ${{ inputs.platforms == '' || contains(inputs.platforms, 'windows') || inputs.platforms == 'all-platforms' }}
uses: actions/download-artifact@v4
with:
name: maven-staging-artifacts-windows-x86_64
path: ./artifacts/windows
continue-on-error: true
- name: Download Maven artifacts (macOS x86_64)
if: ${{ inputs.platforms == '' || contains(inputs.platforms, 'macos') || inputs.platforms == 'all-platforms' }}
uses: actions/download-artifact@v4
with:
name: maven-staging-artifacts-macos-x86_64
path: ./artifacts/macos-x86_64
continue-on-error: true
- name: Download Maven artifacts (macOS aarch64)
if: ${{ inputs.platforms == '' || contains(inputs.platforms, 'macos') || inputs.platforms == 'all-platforms' }}
uses: actions/download-artifact@v4
with:
name: maven-staging-artifacts-macos-aarch64
path: ./artifacts/macos-aarch64
continue-on-error: true
- name: Test Maven deployment (dry run)
env:
VERSION: ${{ needs.build-maven-artifacts.outputs.version-info }}
run: |
echo "=== Maven Deployment Test (Dry Run) ==="
echo "Version: $VERSION"
echo "Repository: GitHub Packages (staging)"
# List artifacts to be deployed by platform
echo "Artifacts ready for deployment:"
for platform_dir in ./artifacts/*/; do
if [ -d "$platform_dir" ]; then
platform_name=$(basename "$platform_dir")
echo "Platform: $platform_name"
find "$platform_dir" -name "*.jar" -exec basename {} \; | sed 's/^/ - /'
fi
done
# Create test Maven settings
mkdir -p ~/.m2
cat > ~/.m2/settings.xml << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0">
<servers>
<server>
<id>github</id>
<username>${env.GITHUB_ACTOR}</username>
<password>${env.GITHUB_TOKEN}</password>
</server>
</servers>
</settings>
EOF
# Simulate deployment validation for each platform
total_jars=0
valid_jars=0
for jar_file in $(find ./artifacts -name "*.jar"); do
jar_name=$(basename "$jar_file")
platform=$(dirname "$jar_file" | sed 's|./artifacts/||')
total_jars=$((total_jars + 1))
echo "[$platform] Testing: $jar_name"
# Test JAR integrity
if jar tf "$jar_file" > /dev/null 2>&1; then
echo " ✓ JAR integrity verified"
valid_jars=$((valid_jars + 1))
else
echo " ❌ JAR integrity check failed"
fi
done
echo "Validation summary: $valid_jars/$total_jars JARs passed integrity check"
if [ $valid_jars -ne $total_jars ]; then
echo "❌ Some artifacts failed validation"
exit 1
fi
echo "🎉 Dry run deployment test passed!"
test-java-examples-maven:
name: "Test Java Examples with Maven Artifacts (${{ matrix.platform }})"
runs-on: ${{ matrix.os }}
needs: [detect-changes, build-maven-artifacts, build-maven-artifacts-windows, build-maven-artifacts-macos-x86_64, build-maven-artifacts-macos-aarch64]
if: ${{ always() && needs.detect-changes.outputs.should-test == 'true' && needs.build-maven-artifacts.outputs.artifacts-created == 'true' }}
continue-on-error: true # Non-blocking failures
strategy:
fail-fast: false
matrix:
include:
- platform: "Linux"
os: "ubuntu-latest"
artifact-name: "maven-staging-artifacts-linux-x86_64"
artifact-path: "linux"
- platform: "Windows"
os: "windows-latest"
artifact-name: "maven-staging-artifacts-windows-x86_64"
artifact-path: "windows"
- platform: "macOS-x86_64"
os: "macos-13"
artifact-name: "maven-staging-artifacts-macos-x86_64"
artifact-path: "macos-x86_64"
- platform: "macOS-aarch64"
os: "macos-latest"
artifact-name: "maven-staging-artifacts-macos-aarch64"
artifact-path: "macos-aarch64"
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Install timeout command on macOS
if: ${{ startsWith(matrix.platform, 'macOS') }}
run: |
# Install GNU coreutils which includes gtimeout
brew install coreutils
echo "Installed gtimeout: $(which gtimeout)"
- name: Download Maven artifacts (${{ matrix.platform }})
uses: actions/download-artifact@v4
with:
name: ${{ matrix.artifact-name }}
path: ./maven-artifacts/${{ matrix.artifact-path }}
continue-on-error: true
- name: Cache Maven dependencies
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-examples-${{ hashFiles('**/pom-examples.xml*') }}
restore-keys: |
${{ runner.os }}-maven-examples-
${{ runner.os }}-maven-
- name: Test Java Examples (Unix)
if: ${{ matrix.platform != 'Windows' }}
id: test-examples-unix
shell: bash
run: |
echo "=== Java Examples Maven Integration Test (${{ matrix.platform }}) ==="
# Test one representative example from each category
cd HDF5Examples/JAVA
# Get absolute path to maven artifacts for this platform
MAVEN_ARTIFACTS_DIR="$(realpath ../../maven-artifacts/${{ matrix.artifact-path }})"
echo "Maven artifacts directory (${{ matrix.platform }}): $MAVEN_ARTIFACTS_DIR"
# Find HDF5 JAR files (not dependencies like slf4j) - use platform-specific artifacts
HDF5_JAR=$(find "$MAVEN_ARTIFACTS_DIR" -name "*hdf5*.jar" -o -name "jarhdf5*.jar" | head -1)
if [ -z "$HDF5_JAR" ]; then
echo "❌ No HDF5 JAR files found for testing"
echo "Available JAR files:"
find "$MAVEN_ARTIFACTS_DIR" -name "*.jar"
exit 1
fi
echo "Using HDF5 JAR file: $HDF5_JAR"
# Also find any dependency JARs - only include slf4j-api and slf4j-simple, exclude slf4j-nop to avoid conflicts
DEP_JARS=$(find "$MAVEN_ARTIFACTS_DIR" -name "slf4j-api*.jar" -o -name "slf4j-simple*.jar")
if [ -n "$DEP_JARS" ]; then
echo "Found dependency JARs:"
echo "$DEP_JARS"
else
echo "No SLF4J dependency JARs found in artifacts, downloading them directly..."
# Download SLF4J dependencies directly using Maven
SLF4J_VERSION="2.0.16"
TEMP_POM="$MAVEN_ARTIFACTS_DIR/temp-pom.xml"
# Create a minimal POM to download dependencies using echo
echo '<?xml version="1.0" encoding="UTF-8"?>' > "$TEMP_POM"
echo '<project xmlns="http://maven.apache.org/POM/4.0.0"' >> "$TEMP_POM"
echo ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' >> "$TEMP_POM"
echo ' xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">' >> "$TEMP_POM"
echo ' <modelVersion>4.0.0</modelVersion>' >> "$TEMP_POM"
echo ' <groupId>temp</groupId>' >> "$TEMP_POM"
echo ' <artifactId>temp</artifactId>' >> "$TEMP_POM"
echo ' <version>1.0</version>' >> "$TEMP_POM"
echo ' <dependencies>' >> "$TEMP_POM"
echo ' <dependency>' >> "$TEMP_POM"
echo ' <groupId>org.slf4j</groupId>' >> "$TEMP_POM"
echo ' <artifactId>slf4j-api</artifactId>' >> "$TEMP_POM"
echo ' <version>2.0.16</version>' >> "$TEMP_POM"
echo ' </dependency>' >> "$TEMP_POM"
echo ' <dependency>' >> "$TEMP_POM"
echo ' <groupId>org.slf4j</groupId>' >> "$TEMP_POM"
echo ' <artifactId>slf4j-simple</artifactId>' >> "$TEMP_POM"
echo ' <version>2.0.16</version>' >> "$TEMP_POM"
echo ' </dependency>' >> "$TEMP_POM"
echo ' </dependencies>' >> "$TEMP_POM"
echo '</project>' >> "$TEMP_POM"
# Download dependencies
if (cd "$MAVEN_ARTIFACTS_DIR" && mvn -f temp-pom.xml dependency:copy-dependencies -DoutputDirectory=. -DincludeScope=runtime -q); then
# Clean up temporary POM
rm -f "$TEMP_POM"
# Re-scan for dependency JARs
DEP_JARS=$(find "$MAVEN_ARTIFACTS_DIR" -name "slf4j-api*.jar" -o -name "slf4j-simple*.jar")
if [ -n "$DEP_JARS" ]; then
echo "Successfully downloaded SLF4J dependencies:"
echo "$DEP_JARS"
else
echo "Failed to download SLF4J dependencies"
fi
else
echo "Error downloading dependencies with Maven"
rm -f "$TEMP_POM"
fi
fi
FAILED_EXAMPLES=""
TOTAL_EXAMPLES=0
PASSED_EXAMPLES=0
# Test representative examples from each category
for category in H5D H5T H5G TUTR; do
if [ -d "$category" ]; then
cd "$category"
# Find first .java file in category
EXAMPLE_FILE=$(ls *.java | head -1)
if [ -f "$EXAMPLE_FILE" ]; then
TOTAL_EXAMPLES=$((TOTAL_EXAMPLES + 1))
example_name=$(basename "$EXAMPLE_FILE" .java)
echo "--- Testing $category/$example_name ---"
# Build classpath with HDF5 JAR and dependencies (already absolute paths)
CLASSPATH="$HDF5_JAR"
if [ -n "$DEP_JARS" ]; then
for dep_jar in $DEP_JARS; do
CLASSPATH="$CLASSPATH:$dep_jar"
done
fi
echo "Using classpath: $CLASSPATH"
# Test compilation
if javac -cp "$CLASSPATH" "$EXAMPLE_FILE" 2>&1; then
echo "✓ Compilation successful for $category/$example_name"
# Test execution (with cross-platform timeout)
if command -v gtimeout >/dev/null 2>&1; then
# macOS with GNU coreutils timeout
EXEC_RESULT=$(gtimeout 10s java -cp ".:$CLASSPATH" "$example_name" >/tmp/${example_name}.out 2>&1; echo $?)
elif command -v timeout >/dev/null 2>&1; then
# Linux/Windows with timeout command
EXEC_RESULT=$(timeout 10s java -cp ".:$CLASSPATH" "$example_name" >/tmp/${example_name}.out 2>&1; echo $?)
else
# Fallback - run without timeout (Java examples should complete quickly)
echo "Note: Running without timeout"
java -cp ".:$CLASSPATH" "$example_name" >/tmp/${example_name}.out 2>&1
EXEC_RESULT=$?
fi
if [ "$EXEC_RESULT" -eq 0 ]; then
# Basic output validation
if grep -q -i -E "(dataset|datatype|group|success|created|written|read)" /tmp/${example_name}.out && \
! grep -q -i -E "(error|exception|failed|cannot)" /tmp/${example_name}.out; then
echo "✓ Execution and validation successful for $category/$example_name"
PASSED_EXAMPLES=$((PASSED_EXAMPLES + 1))
else
echo "✗ Output validation failed for $category/$example_name"
echo "Output:"
cat /tmp/${example_name}.out
FAILED_EXAMPLES="$FAILED_EXAMPLES $category/$example_name"
fi
else
# Check if failure is due to expected native library issue (acceptable for Maven-only testing)
if grep -q "UnsatisfiedLinkError.*hdf5_java.*java.library.path" /tmp/${example_name}.out; then
echo "✓ Expected native library error for Maven-only testing: $category/$example_name"
echo " (This confirms JAR structure is correct)"
PASSED_EXAMPLES=$((PASSED_EXAMPLES + 1))
else
echo "✗ Unexpected execution failure for $category/$example_name"
echo "Output:"
cat /tmp/${example_name}.out
FAILED_EXAMPLES="$FAILED_EXAMPLES $category/$example_name"
fi
fi
else
echo "✗ Compilation failed for $category/$example_name"
FAILED_EXAMPLES="$FAILED_EXAMPLES $category/$example_name"
fi
fi
cd ..
fi
done
echo "=== Java Examples Test Summary (${{ matrix.platform }}) ==="
echo "Total representative examples tested: $TOTAL_EXAMPLES"
echo "Passed: $PASSED_EXAMPLES"
echo "Failed: $((TOTAL_EXAMPLES - PASSED_EXAMPLES))"
if [ -n "$FAILED_EXAMPLES" ]; then
echo "Failed examples:$FAILED_EXAMPLES"
echo "❌ Some Java examples failed - but continuing (non-blocking)"
echo "test-status=FAILED" >> $GITHUB_OUTPUT
else
echo "✅ All representative Java examples passed!"
echo "test-status=PASSED" >> $GITHUB_OUTPUT
fi
echo "total-examples=$TOTAL_EXAMPLES" >> $GITHUB_OUTPUT
echo "passed-examples=$PASSED_EXAMPLES" >> $GITHUB_OUTPUT
- name: Test Java Examples (Windows)
if: ${{ matrix.platform == 'Windows' }}
id: test-examples-windows
shell: pwsh
run: |
Write-Host "=== Java Examples Maven Integration Test (Windows) ==="
# Test one representative example from each category
Set-Location HDF5Examples/JAVA
# Get absolute path to maven artifacts for this platform
$MAVEN_ARTIFACTS_DIR = Resolve-Path "../../maven-artifacts/${{ matrix.artifact-path }}"
Write-Host "Maven artifacts directory (Windows): $MAVEN_ARTIFACTS_DIR"
# Find HDF5 JAR files (not dependencies like slf4j)
$HDF5_JAR = Get-ChildItem -Path $MAVEN_ARTIFACTS_DIR -Filter "*hdf5*.jar" -Recurse | Select-Object -First 1
if (-not $HDF5_JAR) {
$HDF5_JAR = Get-ChildItem -Path $MAVEN_ARTIFACTS_DIR -Filter "jarhdf5*.jar" -Recurse | Select-Object -First 1
}
if (-not $HDF5_JAR) {
Write-Host "❌ No HDF5 JAR files found for testing"
Write-Host "Available JAR files:"
Get-ChildItem -Path $MAVEN_ARTIFACTS_DIR -Filter "*.jar" -Recurse
exit 1
}
Write-Host "Using HDF5 JAR file: $($HDF5_JAR.FullName)"
# Find dependency JARs - only include slf4j-api and slf4j-simple
$DEP_JARS = @()
$DEP_JARS += Get-ChildItem -Path $MAVEN_ARTIFACTS_DIR -Filter "slf4j-api*.jar" -Recurse
$DEP_JARS += Get-ChildItem -Path $MAVEN_ARTIFACTS_DIR -Filter "slf4j-simple*.jar" -Recurse
if ($DEP_JARS.Count -gt 0) {
Write-Host "Found dependency JARs:"
$DEP_JARS | ForEach-Object { Write-Host " $($_.FullName)" }
} else {
Write-Host "No SLF4J dependency JARs found in artifacts, downloading them directly..."
# Download SLF4J dependencies directly using Maven
$SLF4J_VERSION = "2.0.16"
$TEMP_POM = "$MAVEN_ARTIFACTS_DIR\temp-pom.xml"
# Create a minimal POM to download dependencies using PowerShell strings
Write-Host "Creating temporary POM at: $TEMP_POM"
'<?xml version="1.0" encoding="UTF-8"?>' | Out-File $TEMP_POM -Encoding UTF8
'<project xmlns="http://maven.apache.org/POM/4.0.0"' | Out-File $TEMP_POM -Append -Encoding UTF8
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' | Out-File $TEMP_POM -Append -Encoding UTF8
' xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">' | Out-File $TEMP_POM -Append -Encoding UTF8
' <modelVersion>4.0.0</modelVersion>' | Out-File $TEMP_POM -Append -Encoding UTF8
' <groupId>temp</groupId>' | Out-File $TEMP_POM -Append -Encoding UTF8
' <artifactId>temp</artifactId>' | Out-File $TEMP_POM -Append -Encoding UTF8
' <version>1.0</version>' | Out-File $TEMP_POM -Append -Encoding UTF8
' <dependencies>' | Out-File $TEMP_POM -Append -Encoding UTF8
' <dependency>' | Out-File $TEMP_POM -Append -Encoding UTF8
' <groupId>org.slf4j</groupId>' | Out-File $TEMP_POM -Append -Encoding UTF8
' <artifactId>slf4j-api</artifactId>' | Out-File $TEMP_POM -Append -Encoding UTF8
' <version>2.0.16</version>' | Out-File $TEMP_POM -Append -Encoding UTF8
' </dependency>' | Out-File $TEMP_POM -Append -Encoding UTF8
' <dependency>' | Out-File $TEMP_POM -Append -Encoding UTF8
' <groupId>org.slf4j</groupId>' | Out-File $TEMP_POM -Append -Encoding UTF8
' <artifactId>slf4j-simple</artifactId>' | Out-File $TEMP_POM -Append -Encoding UTF8
' <version>2.0.16</version>' | Out-File $TEMP_POM -Append -Encoding UTF8
' </dependency>' | Out-File $TEMP_POM -Append -Encoding UTF8
' </dependencies>' | Out-File $TEMP_POM -Append -Encoding UTF8
'</project>' | Out-File $TEMP_POM -Append -Encoding UTF8
# Download dependencies
try {
Write-Host "Running Maven command: mvn -f $TEMP_POM dependency:copy-dependencies -DoutputDirectory=$MAVEN_ARTIFACTS_DIR -DincludeScope=runtime -q"
$mvn_result = & mvn -f $TEMP_POM dependency:copy-dependencies "-DoutputDirectory=$MAVEN_ARTIFACTS_DIR" -DincludeScope=runtime -q
$mvn_exit_code = $LASTEXITCODE
# Clean up temporary POM
Remove-Item $TEMP_POM -Force -ErrorAction SilentlyContinue
if ($mvn_exit_code -eq 0) {
# Re-scan for dependency JARs
$DEP_JARS = @()
$DEP_JARS += Get-ChildItem -Path $MAVEN_ARTIFACTS_DIR -Filter "slf4j-api*.jar" -Recurse
$DEP_JARS += Get-ChildItem -Path $MAVEN_ARTIFACTS_DIR -Filter "slf4j-simple*.jar" -Recurse
if ($DEP_JARS.Count -gt 0) {
Write-Host "Successfully downloaded SLF4J dependencies:"
$DEP_JARS | ForEach-Object { Write-Host " $($_.FullName)" }
} else {
Write-Host "Maven succeeded but no SLF4J JARs found"
}
} else {
Write-Host "Maven command failed with exit code: $mvn_exit_code"
Write-Host "Maven output: $mvn_result"
}
} catch {
Write-Host "Error downloading dependencies: $($_.Exception.Message)"
}
}
$FAILED_EXAMPLES = @()
$TOTAL_EXAMPLES = 0
$PASSED_EXAMPLES = 0
# Test representative examples from each category
foreach ($category in @("H5D", "H5T", "H5G", "TUTR")) {
if (Test-Path $category) {
Set-Location $category
# Find first .java file in category
$EXAMPLE_FILE = Get-ChildItem -Filter "*.java" | Select-Object -First 1
if ($EXAMPLE_FILE) {
$TOTAL_EXAMPLES++
$example_name = $EXAMPLE_FILE.BaseName
Write-Host "--- Testing $category/$example_name ---"
# Build classpath with HDF5 JAR and dependencies
$CLASSPATH = $HDF5_JAR.FullName
foreach ($dep_jar in $DEP_JARS) {
$CLASSPATH += ";$($dep_jar.FullName)"
}
Write-Host "Using classpath: $CLASSPATH"
# Test compilation
$compileResult = & javac -cp $CLASSPATH $EXAMPLE_FILE.Name 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Host "✓ Compilation successful for $category/$example_name"
# Test execution (with PowerShell timeout)
$output_file = "../../../$example_name.out"
# Use PowerShell's Start-Process with timeout for Windows
try {
# Create temporary files for stdout and stderr
$stdout_file = "$output_file.stdout"
$stderr_file = "$output_file.stderr"
$process = Start-Process -FilePath "java" -ArgumentList "-cp", ".;$CLASSPATH", $example_name -RedirectStandardOutput $stdout_file -RedirectStandardError $stderr_file -NoNewWindow -PassThru
# Wait for the process with timeout
if ($process.WaitForExit(10000)) { # 10 seconds in milliseconds
$execResult = $process.ExitCode
# Combine stdout and stderr into single output file
$stdout_content = if (Test-Path $stdout_file) {
try { Get-Content $stdout_file -Raw -ErrorAction SilentlyContinue } catch { "" }
} else { "" }
$stderr_content = if (Test-Path $stderr_file) {
try { Get-Content $stderr_file -Raw -ErrorAction SilentlyContinue } catch { "" }
} else { "" }
$combined_content = "$stdout_content$stderr_content"
if ([string]::IsNullOrWhiteSpace($combined_content)) {
$combined_content = "No output generated"
}
$combined_content | Out-File $output_file -Encoding UTF8
# Clean up temporary files
if (Test-Path $stdout_file) { Remove-Item $stdout_file -Force }
if (Test-Path $stderr_file) { Remove-Item $stderr_file -Force }
} else {
# Process timed out
try { $process.Kill() } catch { }
$execResult = 1
"Process timed out after 10 seconds" | Out-File $output_file -Encoding UTF8
# Clean up temporary files
if (Test-Path $stdout_file) { Remove-Item $stdout_file -Force }
if (Test-Path $stderr_file) { Remove-Item $stderr_file -Force }
}
} catch {
$execResult = 1
"Execution error: $($_.Exception.Message)" | Out-File $output_file -Encoding UTF8
}
if ($execResult -eq 0) {
# Basic output validation
$content = Get-Content $output_file -Raw
if (($content -match "(?i)(dataset|datatype|group|success|created|written|read)") -and
($content -notmatch "(?i)(error|exception|failed|cannot)")) {
Write-Host "✓ Execution and validation successful for $category/$example_name"
$PASSED_EXAMPLES++
} else {
Write-Host "✗ Output validation failed for $category/$example_name"
Write-Host "Output:"
Get-Content $output_file
$FAILED_EXAMPLES += "$category/$example_name"
}
} else {
# Check if failure is due to expected native library issue
$content = Get-Content $output_file -Raw
if ($content -match "UnsatisfiedLinkError.*hdf5_java.*java.library.path") {
Write-Host "✓ Expected native library error for Maven-only testing: $category/$example_name"
Write-Host " (This confirms JAR structure is correct)"
$PASSED_EXAMPLES++
} else {
Write-Host "✗ Unexpected execution failure for $category/$example_name"
Write-Host "Output:"
Get-Content $output_file
$FAILED_EXAMPLES += "$category/$example_name"
}
}
} else {
Write-Host "✗ Compilation failed for $category/$example_name"
$FAILED_EXAMPLES += "$category/$example_name"
}
}
Set-Location ..
}
}
Write-Host "=== Java Examples Test Summary (Windows) ==="
Write-Host "Total representative examples tested: $TOTAL_EXAMPLES"
Write-Host "Passed: $PASSED_EXAMPLES"
Write-Host "Failed: $($TOTAL_EXAMPLES - $PASSED_EXAMPLES)"
if ($FAILED_EXAMPLES.Count -gt 0) {
Write-Host "Failed examples: $($FAILED_EXAMPLES -join ' ')"
Write-Host "❌ Some Java examples failed - but continuing (non-blocking)"
echo "test-status=FAILED" >> $env:GITHUB_OUTPUT
} else {
Write-Host "✅ All representative Java examples passed!"
echo "test-status=PASSED" >> $env:GITHUB_OUTPUT
}
echo "total-examples=$TOTAL_EXAMPLES" >> $env:GITHUB_OUTPUT
echo "passed-examples=$PASSED_EXAMPLES" >> $env:GITHUB_OUTPUT
- name: Upload failure artifacts (Java Examples)
if: steps.test-examples-unix.outputs.test-status == 'FAILED' || steps.test-examples-windows.outputs.test-status == 'FAILED'
uses: actions/upload-artifact@v4
with:
name: java-examples-staging-failure-${{ matrix.platform }}-${{ github.run_id }}
path: |
/tmp/*.out
*.out
HDF5Examples/JAVA/*/*.class
HDF5Examples/JAVA/*/*.h5
retention-days: 7
comment-pr:
name: Comment on Pull Request
runs-on: ubuntu-latest
needs: [detect-changes, build-maven-artifacts, build-maven-artifacts-windows, build-maven-artifacts-macos-x86_64, build-maven-artifacts-macos-aarch64, test-maven-deployment]
if: ${{ github.event_name == 'pull_request' && needs.detect-changes.outputs.should-test == 'true' && needs.build-maven-artifacts.result == 'success' && needs.test-maven-deployment.result == 'success' }}
steps:
- name: Generate comment body
id: comment
run: |
COMMENT="## ✅ Maven Staging Tests Passed
Maven artifacts successfully generated and validated for version \`${{ needs.build-maven-artifacts.outputs.version-info }}\`.
Ready for Maven deployment to GitHub Packages."
echo "comment<<EOF" >> $GITHUB_OUTPUT
echo "$COMMENT" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Comment on PR
# Skip commenting if running from a fork due to permission restrictions
if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
try {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: process.env.COMMENT_BODY
});
console.log('✅ Comment posted successfully');
} catch (error) {
console.log('❌ Failed to post comment:', error.message);
console.log('This may be due to insufficient permissions or fork restrictions');
// Don't fail the workflow if commenting fails
}
env:
COMMENT_BODY: ${{ steps.comment.outputs.comment }}
- name: Output test results (fallback)
if: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
run: |
echo "==========================================="
echo "✅ Maven Staging Tests Passed"
echo "Maven artifacts successfully generated and validated for version ${{ needs.build-maven-artifacts.outputs.version-info }}"
echo "Ready for Maven deployment to GitHub Packages"
echo "==========================================="
echo "Note: Running from fork - PR comment skipped due to permission restrictions"
cleanup:
name: Cleanup Staging Artifacts
runs-on: ubuntu-latest
needs: [detect-changes, build-maven-artifacts, build-maven-artifacts-windows, build-maven-artifacts-macos-x86_64, build-maven-artifacts-macos-aarch64, test-maven-deployment]
if: ${{ always() && needs.detect-changes.outputs.should-test == 'true' }}
steps:
- name: Cleanup summary
run: |
echo "=== Maven Staging Cleanup ==="
echo "Artifacts will be automatically cleaned up after 7 days"
echo "Build artifacts are stored in GitHub Actions artifacts"
echo "No persistent staging repository cleanup needed"