Refactor Maven publish workflow to create a structured temporary dire… #16
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Copyright 2025 EPAM Systems | |
| # Licensed 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: Maven Publish to Central | |
| on: | |
| # workflow_dispatch: | |
| # inputs: | |
| # version: | |
| # description: 'Release version (e.g., 5.14.4)' | |
| # required: true | |
| # type: string | |
| push: | |
| branches: [ fix/maven-publish ] | |
| env: | |
| REPOSITORY_URL: 'https://maven.pkg.github.com' | |
| PACKAGE: 'com.epam.reportportal' | |
| ARTIFACT: 'commons-bom' | |
| SONATYPE_CENTRAL_API: 'https://central.sonatype.com/api/v1/publisher' | |
| VERSION: '5.14.4' # Test version for automatic runs | |
| jobs: | |
| publish: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up JDK 11 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '11' | |
| - name: Get variables | |
| run: | | |
| echo "PACKAGE_PATH=`echo ${{ env.PACKAGE }} | sed 's/\./\//g'`" >> $GITHUB_ENV | |
| echo "VERSION=${{ env.VERSION }}" >> $GITHUB_ENV | |
| echo "ARTIFACT_NAME=${ARTIFACT}-${VERSION}" >> $GITHUB_ENV | |
| - name: Create authentication token | |
| run: | | |
| # Create base64 encoded token for Sonatype Central API | |
| # According to the API docs: base64(username:password) | |
| echo "AUTH_TOKEN=$(printf "%s:%s" "${{ secrets.SONATYPE_USER }}" "${{ secrets.SONATYPE_PASSWORD }}" | base64)" >> $GITHUB_ENV | |
| - name: Download artifacts from GitHub Packages | |
| run: | | |
| # Define the files to download | |
| FILES=( | |
| "${ARTIFACT_NAME}.pom" | |
| "${ARTIFACT_NAME}.pom.asc" | |
| "${ARTIFACT_NAME}.pom.md5" | |
| "${ARTIFACT_NAME}.pom.sha1" | |
| ) | |
| echo "Downloading artifacts for version: $VERSION" | |
| for file in "${FILES[@]}"; do | |
| URL="${REPOSITORY_URL}/${{ github.repository }}/${PACKAGE_PATH}/${ARTIFACT}/$VERSION/$file" | |
| echo "Downloading: $file from $URL" | |
| # Download with authentication | |
| curl -f -u "${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}" \ | |
| -H "Accept: application/octet-stream" \ | |
| -L -o "$file" "$URL" | |
| if [ ! -f "$file" ]; then | |
| echo "ERROR: Failed to download $file" >&2 | |
| exit 1 | |
| fi | |
| echo "Successfully downloaded: $file ($(wc -c < "$file") bytes)" | |
| done | |
| echo "All artifacts downloaded successfully" | |
| ls -la *.pom* | |
| - name: Create deployment bundle | |
| run: | | |
| echo "Creating deployment bundle..." | |
| # Define specific files to bundle (exactly what we downloaded) | |
| FILES=( | |
| "${ARTIFACT_NAME}.pom" | |
| "${ARTIFACT_NAME}.pom.asc" | |
| "${ARTIFACT_NAME}.pom.md5" | |
| "${ARTIFACT_NAME}.pom.sha1" | |
| ) | |
| echo 'Files to bundle:' | |
| echo "${FILES[@]}" | |
| # Verify all files exist | |
| for file in "${FILES[@]}"; do | |
| if [ ! -f "$file" ]; then | |
| echo "ERROR: Required file $file not found!" >&2 | |
| exit 1 | |
| fi | |
| done | |
| # Create the bundle ZIP file (Sonatype Central accepts ZIP files) | |
| BUNDLE_FILE="bundle.zip" | |
| # Create Maven repository structure in temporary directory | |
| mkdir -p temp_bundle/${PACKAGE_PATH}/${ARTIFACT}/${VERSION} | |
| cp "${FILES[@]}" temp_bundle/${PACKAGE_PATH}/${ARTIFACT}/${VERSION}/ | |
| cd temp_bundle | |
| # Create ZIP with proper Maven repository structure | |
| zip -r ../${BUNDLE_FILE} . | |
| cd .. | |
| # Clean up temp directory | |
| rm -rf temp_bundle | |
| echo "Bundle created: ${BUNDLE_FILE} ($(wc -c < ${BUNDLE_FILE}) bytes)" | |
| echo "Bundle contents:" | |
| unzip -l ${BUNDLE_FILE} | |
| # Export the variable for the next step | |
| echo "BUNDLE_FILE=${BUNDLE_FILE}" >> $GITHUB_ENV | |
| - name: Upload bundle to Sonatype Central | |
| run: | | |
| echo "Uploading bundle to Sonatype Central..." | |
| # Debug: Check if bundle file exists | |
| echo "Current directory: $(pwd)" | |
| echo "Files in current directory:" | |
| ls -la | |
| # Set bundle file name directly since variable might not be passed | |
| BUNDLE_FILE="bundle.zip" | |
| echo "BUNDLE_FILE: ${BUNDLE_FILE}" | |
| if [ ! -f "${BUNDLE_FILE}" ]; then | |
| echo "ERROR: Bundle file ${BUNDLE_FILE} not found!" >&2 | |
| exit 1 | |
| fi | |
| echo "Bundle file size: $(wc -c < ${BUNDLE_FILE}) bytes" | |
| # Upload the bundle using the new Central API (following official docs) | |
| RESPONSE=$(curl -s -w "\n%{http_code}" \ | |
| -X POST \ | |
| -H "Authorization: Bearer $AUTH_TOKEN" \ | |
| --form "bundle=@${BUNDLE_FILE}" \ | |
| "$SONATYPE_CENTRAL_API/upload") | |
| # Extract HTTP status code and response body | |
| HTTP_STATUS=$(echo "$RESPONSE" | tail -n1) | |
| RESPONSE_BODY=$(echo "$RESPONSE" | head -n -1) | |
| echo "Upload response status: $HTTP_STATUS" | |
| echo "Upload response body: $RESPONSE_BODY" | |
| if [ "$HTTP_STATUS" -ne 200 ] && [ "$HTTP_STATUS" -ne 201 ]; then | |
| echo "ERROR: Failed to upload bundle. HTTP status: $HTTP_STATUS" >&2 | |
| echo "Response: $RESPONSE_BODY" >&2 | |
| exit 1 | |
| fi | |
| # Extract deployment ID from response | |
| # For 201 responses, the response body is the deployment ID directly | |
| if [ "$HTTP_STATUS" -eq 201 ]; then | |
| DEPLOYMENT_ID="$RESPONSE_BODY" | |
| else | |
| DEPLOYMENT_ID=$(echo "$RESPONSE_BODY" | jq -r '.deploymentId // empty') | |
| fi | |
| if [ -z "$DEPLOYMENT_ID" ]; then | |
| echo "ERROR: Could not extract deployment ID from response" >&2 | |
| echo "Response: $RESPONSE_BODY" >&2 | |
| exit 1 | |
| fi | |
| echo "Deployment ID: $DEPLOYMENT_ID" | |
| echo "DEPLOYMENT_ID=$DEPLOYMENT_ID" >> $GITHUB_ENV | |
| - name: Monitor deployment status | |
| run: | | |
| echo "Monitoring deployment status for ID: $DEPLOYMENT_ID" | |
| MAX_ATTEMPTS=30 | |
| SLEEP_TIME=30 | |
| for attempt in $(seq 1 $MAX_ATTEMPTS); do | |
| echo "Checking status (attempt $attempt/$MAX_ATTEMPTS)..." | |
| STATUS_RESPONSE=$(curl -s -w "\n%{http_code}" \ | |
| -X POST \ | |
| -H "Authorization: Bearer $AUTH_TOKEN" \ | |
| -H "Content-Type: application/json" \ | |
| "$SONATYPE_CENTRAL_API/status?id=$DEPLOYMENT_ID") | |
| STATUS_CODE=$(echo "$STATUS_RESPONSE" | tail -n1) | |
| STATUS_BODY=$(echo "$STATUS_RESPONSE" | head -n -1) | |
| if [ "$STATUS_CODE" -ne 200 ]; then | |
| echo "ERROR: Failed to get status. HTTP status: $STATUS_CODE" >&2 | |
| echo "Response: $STATUS_BODY" >&2 | |
| exit 1 | |
| fi | |
| DEPLOYMENT_STATE=$(echo "$STATUS_BODY" | jq -r '.deploymentState // empty') | |
| echo "Current deployment state: $DEPLOYMENT_STATE" | |
| case "$DEPLOYMENT_STATE" in | |
| "PUBLISHED") | |
| echo "✅ Deployment successfully published to Maven Central!" | |
| echo "$STATUS_BODY" | jq -r '.purls[]?' | while read purl; do | |
| echo "Published package: $purl" | |
| done | |
| exit 0 | |
| ;; | |
| "FAILED") | |
| echo "❌ Deployment failed!" | |
| echo "$STATUS_BODY" | jq -r '.errors[]?' | while read error; do | |
| echo "Error: $error" | |
| done | |
| exit 1 | |
| ;; | |
| "PENDING"|"VALIDATING"|"VALIDATED"|"PUBLISHING") | |
| echo "⏳ Deployment is in progress ($DEPLOYMENT_STATE)..." | |
| if [ $attempt -lt $MAX_ATTEMPTS ]; then | |
| echo "Waiting $SLEEP_TIME seconds before next check..." | |
| sleep $SLEEP_TIME | |
| fi | |
| ;; | |
| *) | |
| echo "❓ Unknown deployment state: $DEPLOYMENT_STATE" | |
| echo "Full response: $STATUS_BODY" | |
| exit 1 | |
| ;; | |
| esac | |
| done | |
| echo "❌ Timeout waiting for deployment to complete after $MAX_ATTEMPTS attempts" | |
| exit 1 | |
| - name: Success notification | |
| if: success() | |
| run: | | |
| echo "🎉 Successfully published commons-bom version $VERSION to Maven Central!" | |
| echo "Package: $PACKAGE:$ARTIFACT:$VERSION" |