Skip to content
Merged
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
204 changes: 108 additions & 96 deletions .github/workflows/build-artifact.yml
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,6 @@ jobs:
fetch-depth: 1

- name: Setup JFrog CLI
if: needs.prepare-matrix.outputs.has_apps_to_restore == 'true'
uses: jfrog/setup-jfrog-cli@7c95feb32008765e1b4e626b078dfd897c4340ad # v4.4.1
env:
JF_URL: ${{ secrets.JF_ARTIFACTORY_URL }}
Expand All @@ -490,29 +489,111 @@ jobs:
# Ping the server
jf rt ping

- name: Restore cached apps
if: needs.prepare-matrix.outputs.has_apps_to_restore == 'true'
- name: Restore all apps from cache and JFrog
run: |
set -e
set -euo pipefail

# Restore apps that are in cache (from apps_to_restore)
if [ "${{ needs.prepare-matrix.outputs.has_apps_to_restore }}" == "true" ]; then
echo "📦 Restoring cached apps..."
APPS_TO_RESTORE='${{ needs.prepare-matrix.outputs.apps_to_restore }}'

# Process each app in the restore list
echo "$APPS_TO_RESTORE" | jq -c '.[]' | while read -r app_json; do
APP_NAME=$(echo "$app_json" | jq -r '.name')
APP_SHA=$(echo "$app_json" | jq -r '.sha')
APP_PATH=$(echo "$app_json" | jq -r '.path')
SOURCE=$(echo "$app_json" | jq -r '.source')

echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Restoring: $APP_NAME (source: $SOURCE)"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

if [ "$SOURCE" == "jfrog" ]; then
# Restore from JFrog
JFROG_PATH=$(echo "$app_json" | jq -r '.jfrog_path')
ARCHIVE_NAME="${APP_NAME}-${APP_SHA}.tar.gz"

echo "📥 Downloading from JFrog: $JFROG_PATH"

if jf rt download "$JFROG_PATH" "$ARCHIVE_NAME" --flat=true; then
echo "✅ Downloaded successfully"
echo "Extracting to $APP_PATH..."
mkdir -p "$(dirname "$APP_PATH")"
tar -xzf "$ARCHIVE_NAME" -C "$(dirname "$APP_PATH")"

if [ -d "$APP_PATH" ] && [ -f "$APP_PATH/appinfo/info.xml" ]; then
echo "✅ Restored $APP_NAME from JFrog"
else
echo "❌ Failed to extract or validate $APP_NAME"
exit 1
fi

rm -f "$ARCHIVE_NAME"
else
echo "❌ Failed to download from JFrog"
exit 1
fi

echo "📦 Restoring cached apps..."
APPS_TO_RESTORE='${{ needs.prepare-matrix.outputs.apps_to_restore }}'
elif [ "$SOURCE" == "github-cache" ]; then
# Restore from GitHub cache
CACHE_KEY=$(echo "$app_json" | jq -r '.cache_key')

# Process each app in the restore list
echo "$APPS_TO_RESTORE" | jq -c '.[]' | while read -r app_json; do
APP_NAME=$(echo "$app_json" | jq -r '.name')
APP_SHA=$(echo "$app_json" | jq -r '.sha')
APP_PATH=$(echo "$app_json" | jq -r '.path')
SOURCE=$(echo "$app_json" | jq -r '.source')
echo "💾 Restoring from GitHub cache: $CACHE_KEY"

# Use actions/cache/restore in a way that works in a script context
# We need to use gh CLI to restore the cache
if gh cache restore "$CACHE_KEY" --key "$CACHE_KEY"; then
echo "✅ Restored $APP_NAME from GitHub cache"

# Validate restoration
if [ ! -d "$APP_PATH" ] || [ ! -f "$APP_PATH/appinfo/info.xml" ]; then
echo "❌ Validation failed for $APP_NAME"
exit 1
fi
else
echo "❌ Failed to restore from GitHub cache"
exit 1
fi
else
echo "❌ Unknown source: $SOURCE"
exit 1
fi
done

echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Restoring: $APP_NAME (source: $SOURCE)"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ All cached apps restored successfully"
fi

# Also restore newly built apps from JFrog (from apps_to_build)
if [ "${{ needs.prepare-matrix.outputs.has_apps_to_build }}" == "true" ]; then
echo ""
echo "📦 Restoring newly built apps from JFrog..."
APPS_TO_BUILD='${{ needs.prepare-matrix.outputs.apps_to_build }}'
FULL_MATRIX='${{ needs.prepare-matrix.outputs.external_apps_matrix }}'
EFFECTIVE_CACHE_VERSION="${{ needs.prepare-matrix.outputs.effective_cache_version }}"

# Process each app in the build list
echo "$APPS_TO_BUILD" | jq -c '.[]' | while read -r app_json; do
APP_NAME=$(echo "$app_json" | jq -r '.name')
APP_SHA=$(echo "$app_json" | jq -r '.sha')

# Get app path from full matrix
APP_PATH=$(echo "$FULL_MATRIX" | jq -r --arg name "$APP_NAME" '.[] | select(.name == $name) | .path')

if [ "$SOURCE" == "jfrog" ]; then
# Restore from JFrog
JFROG_PATH=$(echo "$app_json" | jq -r '.jfrog_path')
if [ -z "$APP_PATH" ] || [ "$APP_PATH" == "null" ]; then
echo "❌ Could not find path for $APP_NAME in matrix"
exit 1
fi

echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Restoring newly built: $APP_NAME"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

# Construct JFrog path matching what build-external-apps uploaded
JFROG_PATH="${{ env.ARTIFACTORY_REPOSITORY_SNAPSHOT }}/apps/${EFFECTIVE_CACHE_VERSION}/${APP_NAME}/${APP_NAME}-${APP_SHA}.tar.gz"
ARCHIVE_NAME="${APP_NAME}-${APP_SHA}.tar.gz"

echo "📥 Downloading from JFrog: $JFROG_PATH"
Expand All @@ -535,88 +616,19 @@ jobs:
echo "❌ Failed to download from JFrog"
exit 1
fi
done

elif [ "$SOURCE" == "github-cache" ]; then
# Restore from GitHub cache
CACHE_KEY=$(echo "$app_json" | jq -r '.cache_key')

echo "💾 Restoring from GitHub cache: $CACHE_KEY"

# Use actions/cache/restore in a way that works in a script context
# We need to use gh CLI to restore the cache
if gh cache restore "$CACHE_KEY" --key "$CACHE_KEY"; then
echo "✅ Restored $APP_NAME from GitHub cache"

# Validate restoration
if [ ! -d "$APP_PATH" ] || [ ! -f "$APP_PATH/appinfo/info.xml" ]; then
echo "❌ Validation failed for $APP_NAME"
exit 1
fi
else
echo "❌ Failed to restore from GitHub cache"
exit 1
fi
else
echo "❌ Unknown source: $SOURCE"
exit 1
fi
done
echo ""
echo "✅ All newly built apps restored from JFrog successfully"
fi

echo ""
echo "✅ All cached apps restored successfully"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ All apps restored successfully"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
env:
GH_TOKEN: ${{ github.token }}

- name: Download build external apps
uses: actions/download-artifact@v5
with:
pattern: external-app-build-*
path: apps-external/

- name: Reorganize downloaded apps-external artifacts
run: |
cd apps-external/

echo "Initial structure:"
ls -la

# Move contents from external-app-build-* directories to their target directories
for artifact_dir in external-app-build-*; do
if [ -d "$artifact_dir" ]; then
# Extract app name from artifact directory name
app_name=${artifact_dir#external-app-build-}

echo "Processing artifact: $artifact_dir -> $app_name"

# If target directory exists, merge the contents from the artifact directory containing build artifacts
if [ -d "$app_name" ]; then
echo "Target directory $app_name exists, merging contents from $artifact_dir"
# Copy contents from artifact directory to target directory
cp -r "$artifact_dir"/* "$app_name"/
# Remove the now-empty artifact directory
rm -rf "$artifact_dir"
else
# Move the artifact directory to the proper app name
echo "Moving $artifact_dir to $app_name"
mv "$artifact_dir" "$app_name"
fi
fi
done

echo "Reorganization complete. Final structure:"
ls -la

- name: Verify downloaded artifacts structure
run: |
echo "External apps structure:"
ls -la apps-external/
for app_dir in apps-external/*/; do
if [ -d "$app_dir" ]; then
echo "Contents of $app_dir:"
ls -la "$app_dir"
fi
done

- name: Set up node with version from package.json's engines
uses: actions/setup-node@v6
with:
Expand Down Expand Up @@ -698,10 +710,10 @@ jobs:

upload-to-artifactory:
runs-on: self-hosted
# Upload the artifact to the Artifactory repository on PR *OR* on "ionos-dev|ionos-stable|rc/*" branch push defined in the on:push:branches
# Upload the artifact to the Artifactory repository on PR *OR* on "ionos-dev|ionos-stable|rc/*" branch push defined in the on:push:branches *OR* on manual workflow_dispatch
if: |
always() &&
(github.event_name == 'pull_request' || github.ref_name == 'ionos-dev' || github.ref_name == 'ionos-stable' || startsWith(github.ref_name, 'rc/')) &&
(github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' || github.ref_name == 'ionos-dev' || github.ref_name == 'ionos-stable' || startsWith(github.ref_name, 'rc/')) &&
needs.prepare-matrix.result == 'success' &&
(needs.build-external-apps.result == 'success' || needs.build-external-apps.result == 'skipped') &&
needs.build-artifact.result == 'success'
Expand Down
Loading