Skip to content

Commit 58f58be

Browse files
IONOS(ci): rewire hidrive-next-build to consume per-app cached artifacts
Retires the inline app-build path in hidrive-next-build: the job now depends on prepare-matrix + build-apps and restores every app's tarball from JFrog (using the apps_to_restore + apps_to_build outputs from prepare-matrix) before running make -f IONOS/Makefile build_nextcloud_only. - hidrive-next-build now needs: [prepare-matrix, build-apps] - All seven per-app build steps (build_dep_simplesettings_app, build_dep_viewer_app, build_richdocuments_app, build_dep_user_oidc_app, build_dep_nc_ionos_processes_app, build_dep_theming_app, build_dep_ionos_theme) are removed — those builds run in parallel in build-apps instead - A new Restore all apps from JFrog and GitHub cache step iterates the per-app JSON arrays, downloads each tarball from JFrog and extracts it in place, then validates the target path exists - A JFrog credential availability check + assert ensures the job fails fast with a clear diagnostic when the JFrog secret set is incomplete (artifact restore has no graceful degradation path) - Build Nextcloud switches from build_nextcloud to build_nextcloud_only — apps are already on disk so only the core build is needed - Downstream upload-to-artifactory, hidirve-next-artifact-to-ghcr_io, and trigger-remote-dev-worflow needs:/if: are updated to include prepare-matrix + build-apps in their wait list Net effect: each app builds once (in build-apps), all caches via JFrog + GitHub Actions cache, and the final image assembly is purely composition. Signed-off-by: Misha M.-Kupriyanov <kupriyanov@strato.de>
1 parent 13b745d commit 58f58be

1 file changed

Lines changed: 128 additions & 40 deletions

File tree

.github/workflows/hidrive-next-build.yml

Lines changed: 128 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,11 @@ jobs:
305305
306306
hidrive-next-build:
307307
runs-on: ubuntu-latest
308+
needs: [prepare-matrix, build-apps]
309+
if: |
310+
always() &&
311+
needs.prepare-matrix.result == 'success' &&
312+
(needs.build-apps.result == 'success' || needs.build-apps.result == 'skipped')
308313
309314
permissions:
310315
contents: read
@@ -319,6 +324,118 @@ jobs:
319324
with:
320325
submodules: true
321326

327+
- name: Check JFrog credentials
328+
id: jfrog-creds
329+
env:
330+
JF_URL: ${{ secrets.JF_ARTIFACTORY_URL }}
331+
JF_USER: ${{ secrets.JF_ARTIFACTORY_USER }}
332+
JF_ACCESS_TOKEN: ${{ secrets.JF_ACCESS_TOKEN }}
333+
run: |
334+
if [ -n "$JF_URL" ] && [ -n "$JF_USER" ] && [ -n "$JF_ACCESS_TOKEN" ]; then
335+
echo "available=true" >> $GITHUB_OUTPUT
336+
else
337+
echo "available=false" >> $GITHUB_OUTPUT
338+
echo "⚠ Full JFrog credential set not available — artifact restore is not possible"
339+
fi
340+
341+
- name: Assert JFrog credentials are available (required for artifact restore)
342+
if: steps.jfrog-creds.outputs.available != 'true'
343+
run: |
344+
echo "❌ JFrog credentials are required for hidrive-next-build artifact restore."
345+
echo " Set JF_ARTIFACTORY_URL, JF_ARTIFACTORY_USER, and JF_ACCESS_TOKEN secrets."
346+
exit 1
347+
348+
- name: Setup JFrog CLI
349+
if: steps.jfrog-creds.outputs.available == 'true'
350+
uses: jfrog/setup-jfrog-cli@7c95feb32008765e1b4e626b078dfd897c4340ad # v4.4.1
351+
env:
352+
JF_URL: ${{ secrets.JF_ARTIFACTORY_URL }}
353+
JF_USER: ${{ secrets.JF_ARTIFACTORY_USER }}
354+
JF_ACCESS_TOKEN: ${{ secrets.JF_ACCESS_TOKEN }}
355+
356+
- name: Ping JFrog server
357+
if: steps.jfrog-creds.outputs.available == 'true'
358+
run: jf rt ping
359+
360+
- name: Restore all apps from JFrog and GitHub cache
361+
if: steps.jfrog-creds.outputs.available == 'true'
362+
env:
363+
GH_TOKEN: ${{ github.token }}
364+
run: |
365+
set -euo pipefail
366+
EFFECTIVE_VERSION="${{ needs.prepare-matrix.outputs.effective_cache_version }}"
367+
FULL_MATRIX='${{ needs.prepare-matrix.outputs.apps_matrix }}'
368+
369+
# Restore cached apps (from detect-app-cache.sh output)
370+
if [ "${{ needs.prepare-matrix.outputs.has_apps_to_restore }}" == "true" ]; then
371+
echo "Restoring cached apps..."
372+
APPS_TO_RESTORE='${{ needs.prepare-matrix.outputs.apps_to_restore }}'
373+
while read -r app_json; do
374+
APP_NAME=$(echo "$app_json" | jq -r '.name')
375+
APP_PATH=$(echo "$app_json" | jq -r '.path')
376+
SOURCE=$(echo "$app_json" | jq -r '.source')
377+
378+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
379+
echo "Restoring: $APP_NAME (source: $SOURCE)"
380+
381+
if [ "$SOURCE" == "jfrog" ]; then
382+
JFROG_PATH=$(echo "$app_json" | jq -r '.jfrog_path')
383+
ARCHIVE_NAME=$(echo "$app_json" | jq -r '.archive_name // empty')
384+
if [ -z "$ARCHIVE_NAME" ]; then
385+
ARCHIVE_NAME="$(basename "$JFROG_PATH")"
386+
fi
387+
echo "Downloading from JFrog: $JFROG_PATH"
388+
jf rt download "$JFROG_PATH" "$ARCHIVE_NAME" --flat=true
389+
mkdir -p "$(dirname "$APP_PATH")"
390+
tar -xzf "$ARCHIVE_NAME" -C "$(dirname "$APP_PATH")"
391+
rm -f "$ARCHIVE_NAME"
392+
if [ -d "$APP_PATH" ]; then
393+
echo "✅ Restored $APP_NAME from JFrog"
394+
else
395+
echo "❌ Restore validation failed: $APP_PATH not found"
396+
exit 1
397+
fi
398+
399+
elif [ "$SOURCE" == "github-cache" ]; then
400+
CACHE_KEY=$(echo "$app_json" | jq -r '.cache_key')
401+
echo "❌ Cannot restore $APP_NAME from GitHub cache within a shell step."
402+
echo " Cache key: $CACHE_KEY"
403+
echo " GitHub Actions cache requires 'actions/cache/restore@v4' as a dedicated workflow step."
404+
exit 1
405+
fi
406+
done < <(echo "$APPS_TO_RESTORE" | jq -c '.[]')
407+
fi
408+
409+
# Restore newly built apps from JFrog (apps_to_build)
410+
if [ "${{ needs.prepare-matrix.outputs.has_apps_to_build }}" == "true" ]; then
411+
echo "Restoring newly built apps from JFrog..."
412+
APPS_TO_BUILD='${{ needs.prepare-matrix.outputs.apps_to_build }}'
413+
while read -r app_json; do
414+
APP_NAME=$(echo "$app_json" | jq -r '.name')
415+
ARCHIVE_NAME=$(echo "$app_json" | jq -r '.archive_name')
416+
JFROG_PATH=$(echo "$app_json" | jq -r '.jfrog_path')
417+
APP_PATH=$(echo "$FULL_MATRIX" | jq -r --arg name "$APP_NAME" '.[] | select(.name == $name) | .path')
418+
419+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
420+
echo "Restoring newly built: $APP_NAME"
421+
echo "Downloading from JFrog: $JFROG_PATH"
422+
423+
jf rt download "$JFROG_PATH" "$ARCHIVE_NAME" --flat=true
424+
mkdir -p "$(dirname "$APP_PATH")"
425+
tar -xzf "$ARCHIVE_NAME" -C "$(dirname "$APP_PATH")"
426+
rm -f "$ARCHIVE_NAME"
427+
428+
if [ -d "$APP_PATH" ]; then
429+
echo "✅ Restored $APP_NAME from JFrog"
430+
else
431+
echo "❌ Restore validation failed: $APP_PATH not found"
432+
exit 1
433+
fi
434+
done < <(echo "$APPS_TO_BUILD" | jq -c '.[]')
435+
fi
436+
437+
echo "✅ All apps restored"
438+
322439
- name: Set up node with version from package.json's engines
323440
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
324441
with:
@@ -341,41 +458,8 @@ jobs:
341458
- name: Print PHP install
342459
run: php -i && php -m
343460

344-
- name: Build Nextcloud
345-
run: make -f IONOS/Makefile build_nextcloud
346-
347-
- name: Install dependencies & build simplesettings app
348-
env:
349-
CYPRESS_INSTALL_BINARY: 0
350-
PUPPETEER_SKIP_DOWNLOAD: true
351-
run: make -f IONOS/Makefile build_dep_simplesettings_app
352-
353-
- name: Install dependencies & build viewer app
354-
env:
355-
CYPRESS_INSTALL_BINARY: 0
356-
PUPPETEER_SKIP_DOWNLOAD: true
357-
run: make -f IONOS/Makefile build_dep_viewer_app
358-
359-
- name: Install dependencies & build richdocuments app
360-
run: make -f IONOS/Makefile build_richdocuments_app
361-
362-
- name: Install dependencies & build user_oidc app
363-
env:
364-
CYPRESS_INSTALL_BINARY: 0
365-
PUPPETEER_SKIP_DOWNLOAD: true
366-
run: make -f IONOS/Makefile build_dep_user_oidc_app
367-
368-
- name: Install dependencies for external apps nc_ionos_processes
369-
run: make -f IONOS/Makefile build_dep_nc_ionos_processes_app
370-
371-
- name: Build Custom CSS
372-
run: make -f IONOS/Makefile build_dep_theming_app
373-
374-
- name: Install dependencies & build IONOS theme custom elements
375-
env:
376-
CYPRESS_INSTALL_BINARY: 0
377-
PUPPETEER_SKIP_DOWNLOAD: true
378-
run: make -f IONOS/Makefile build_dep_ionos_theme
461+
- name: Build Nextcloud (core only — apps restored from cache)
462+
run: make -f IONOS/Makefile build_nextcloud_only
379463

380464
- name: Add config partials
381465
run: make -f IONOS/Makefile add_config_partials
@@ -386,7 +470,6 @@ jobs:
386470
run: |
387471
echo "${{ github.run_number }}" > .buildnumber
388472
echo "✅ Build number injected: ${{ github.run_number }}"
389-
echo "📄 File created: .buildnumber"
390473
cat .buildnumber
391474
392475
- name: Zip dependencies
@@ -422,11 +505,16 @@ jobs:
422505
423506
upload-to-artifactory:
424507
runs-on: self-hosted
425-
# Upload the artifact to the Artifactory repository on PR *OR* on "ionos-dev|ionos-stable" branch push defined in the on:push:branches
426-
if: github.event_name == 'pull_request' || github.ref_name == 'ionos-dev' || github.ref_name == 'ionos-stable'
508+
# Upload the artifact to the Artifactory repository on PR *OR* on "ionos-dev|ionos-stable" branch push
509+
if: |
510+
always() &&
511+
(github.event_name == 'pull_request' || github.ref_name == 'ionos-dev' || github.ref_name == 'ionos-stable') &&
512+
needs.prepare-matrix.result == 'success' &&
513+
(needs.build-apps.result == 'success' || needs.build-apps.result == 'skipped') &&
514+
needs.hidrive-next-build.result == 'success'
427515
428516
name: Push to artifactory
429-
needs: hidrive-next-build
517+
needs: [prepare-matrix, build-apps, hidrive-next-build]
430518

431519
outputs:
432520
ARTIFACTORY_LAST_BUILD_PATH: ${{ steps.artifactory_upload.outputs.ARTIFACTORY_LAST_BUILD_PATH }}
@@ -498,7 +586,7 @@ jobs:
498586
packages: write
499587

500588
name: Push artifact to ghcr.io
501-
needs: hidrive-next-build
589+
needs: [prepare-matrix, build-apps, hidrive-next-build]
502590

503591
steps:
504592
- name: Download artifact zip

0 commit comments

Comments
 (0)