Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
4672343
IONOS(config): update submodule 6c76022 (fix(submodule-trigger-workfl…
github-actions[bot] Nov 7, 2025
19debab
IONOS(config): update submodule (remove default footer links)
Arsalanulhaq Nov 6, 2025
c17b4ea
IONOS(ncw-config, mail): enable admin delegated settings for mail app
tanyaka Nov 7, 2025
2e0caa5
Revert "IONOS(config): remove user_oidc submodule and build targets"
tanyaka Nov 7, 2025
f56fc12
IONOS(config): update submodule 1395a7b445f (re-add and disable user_…
tanyaka Nov 7, 2025
1836440
IONOS(config): update submodule 945436e (fix(Makefile): add precheck …
github-actions[bot] Nov 11, 2025
50ab7e1
IONOS(build): sort build targets for external apps
printminion-co Nov 10, 2025
4577d1a
IONOS(build): enable npm for ncw_mailtemplate in build configuration
printminion-co Nov 11, 2025
c55f9bc
IONOS(build): add matrix validation and install dependencies in build…
printminion-co Nov 10, 2025
f990419
IONOS(config): update submodule 3dc76d7 (refactor(Makefile): refactor…
github-actions[bot] Nov 12, 2025
44eb5dc
IONOS(build): add missing password_policy app to build configuration
printminion-co Nov 11, 2025
61b997c
IONOS(user_ldap): handle user mapping exceptions for user_limit reached
Arsalanulhaq Nov 17, 2025
00a6ba4
IONOS(core-notifier): reduce the user_limit_reached message
tanyaka Nov 19, 2025
fda334f
IONOS(config): update submodule c18550d (fix(Makefile): add support f…
github-actions[bot] Dec 12, 2025
18ea03b
IONOS(theming): fix user bubble color
bromiesTM Nov 6, 2025
5ce432c
IONOS(theming): adjust tasks app theming
bromiesTM Nov 6, 2025
86d5b7e
IONOS(mail): update submodule to hide new mail creation for existing …
seriAlizations Nov 13, 2025
547ab71
IONOS(theming): improve app manager colors
bromiesTM Nov 6, 2025
ee2edc9
IONOS(theming): improve chat app colors
bromiesTM Nov 6, 2025
5835b28
IONOS(theming): fix search button hover color
bromiesTM Nov 10, 2025
146a674
IONOS(theming): fix search menu darkmode color
bromiesTM Nov 10, 2025
28c2135
IONOS(theming): adjust colors for calendar app
bromiesTM Nov 10, 2025
e52b4ea
IONOS(theming): load all css files from theme folder
bromiesTM Nov 10, 2025
f5db971
IONOS(theming): adjust profile app colors
bromiesTM Nov 10, 2025
94eea8b
IONOS(theming): fix assistant navigation text color
bromiesTM Nov 10, 2025
518351e
IONOS(theming): fix notification settings colors
bromiesTM Nov 10, 2025
093e19f
IONOS(theming): fix notes suggestion colors
bromiesTM Nov 12, 2025
c5c03c4
IONOS(theming): fix tables app colors
bromiesTM Nov 12, 2025
f66e563
IONOS(theming): rename css variable to reflect broader usage
bromiesTM Nov 12, 2025
cc877dc
IONOS(theming): fix missing hover color for secondary button
bromiesTM Nov 20, 2025
16fd978
IONOS(theming): make user bubble visible everywhere
bromiesTM Nov 20, 2025
39ef51f
IONOS(theming): invert activity timeline icons in darkmode
bromiesTM Nov 20, 2025
f84451f
IONOS(theming/deck): fix icon hover color
bromiesTM Nov 20, 2025
deecb25
IONOS(build): sort build targets for external apps
printminion-co Nov 10, 2025
583640a
IONOS(build): fixup build artifact file matrix for external apps
Arsalanulhaq Nov 21, 2025
820b874
IONOS(theming): load all css files from theme folder
bromiesTM Nov 10, 2025
d5ec50c
IONOS(theming): fix collabora vertical shift and copilot suggestion f…
seriAlizations Nov 13, 2025
51f3493
IONOS(ncw_mailtemplate): update submodule (fix broken mails)
bromiesTM Dec 3, 2025
9b9c9c7
IONOS(theming): fix text editor background color
bromiesTM Dec 4, 2025
0721b4f
IONOS(AppsMenu): update submodule (fixed styling)
bromiesTM Dec 8, 2025
1fe6867
IONOS(theming): use static favicon in all apps for consistent branding
tanyaka Dec 8, 2025
e75abe6
IONOS(theming): fix file viewer background color
tanyaka Dec 9, 2025
aa5b5be
IONOS(ncw_mailtemplate) update submodule (adjust mail styling)
bromiesTM Dec 10, 2025
445083b
IONOS(theming): fix breadcrumb button size
bromiesTM Dec 8, 2025
cdf1f13
IONOS(theming): change target dialog button colors
bromiesTM Dec 8, 2025
a79215c
IONOS(tests): add tests for developer documentation link generation
Arsalanulhaq Dec 2, 2025
8217b8a
IONOS(appsettings): conditionally display developer documentation lin…
Arsalanulhaq Dec 2, 2025
0ab4f23
IONOS(config): add developer_documentation_url boolean and build ncw …
Arsalanulhaq Dec 15, 2025
86635c1
IONOS(theming): fix table entry edit button colors
bromiesTM Dec 8, 2025
94e536d
IONOS(theming): add missing color definition for --ion-color-cool-gre…
tanyaka Dec 11, 2025
d850137
IONOS(theming): tables app: refine table header and editor styles for…
tanyaka Dec 11, 2025
124e5cd
IONOS(theming): adjust position of grid button in file list
Arsalanulhaq Dec 11, 2025
faf78a7
IONOS(build): copy build-artifact.yml as build-artifact-original.yml
printminion-co Nov 12, 2025
4ed5ba7
IONOS(build): update artifact filename to include '-original' suffix
printminion-co Nov 12, 2025
04239d3
IONOS(build): update fetch-depth in build-artifact.yml to integer format
printminion-co Nov 12, 2025
dcc7e3a
IONOS(build): update action versions for improved functionality and c…
printminion-co Nov 12, 2025
e074c0b
IONOS(build): add retry logic for GitLab pipeline trigger
printminion-co Nov 12, 2025
58b1c95
IONOS(build): add retry logic for artifact upload in build-artifact.yml
printminion-co Nov 12, 2025
5994f43
IONOS(build): fix step ID naming in build-artifact.yml for consistency
printminion-co Nov 12, 2025
28be12f
IONOS(build): generate apps matrix dynamically from Makefile
printminion-co Nov 12, 2025
81e45a5
IONOS(build): optimize build workflow - only rebuild changed apps
printminion-co Nov 11, 2025
ad04de6
IONOS(build): ensure jobs depend on successful matrix preparation
printminion-co Nov 12, 2025
c7ce243
IONOS(build): add manual trigger for comparison testing in build-arti…
printminion-co Nov 13, 2025
12d3b7a
IONOS(ci): Add app cache detection for JFrog build pipeline
bromiesTM Dec 15, 2025
53765ad
IONOS(ci): Refactor cache detection logic into separate script
bromiesTM Dec 15, 2025
3609eab
IONOS(ci): use cache version env for jfrog invalidation
bromiesTM Dec 17, 2025
db7eab7
IONOS(ci): fix typos and spacing
bromiesTM Dec 17, 2025
767a7d4
IONOS(theming): fix themefolder settings dropdown colors
bromiesTM Dec 15, 2025
6dcead8
IONOS(Theming): fix the background color in darkmode
tanyaka Dec 17, 2025
4c256ea
IONOS(theming): update checkbox-radio-switch styles for better visibi…
Arsalanulhaq Dec 16, 2025
06856e1
fix(comments): Check comment object
nickvergessen Dec 11, 2025
1f8fde6
fix(NewUserDialog): allow to deselect a group from the list
Antreesy Oct 23, 2025
b91f0d1
IONOS(NewUserDialog): update group options to exclude admin from sub-…
Arsalanulhaq Dec 23, 2025
43864f1
IONOS(build): add ping step for JFrog server in build-artifact.yml
printminion-co Dec 22, 2025
cdb0f4f
IONOS(theming): fix secondary button background color hover state
printminion-co Jan 5, 2026
1ce5e67
IONOS(ci): fix boolean comparison
bromiesTM Jan 6, 2026
4b8e106
Revert "IONOS(ci): fix boolean comparison"
printminion-co Jan 6, 2026
2cd55f3
IONOS(build): enhance remote trigger job with detailed condition checks
printminion-co Jan 6, 2026
e88bfc3
IONOS(build): add debug pipeline status job with detailed analysis
printminion-co Jan 6, 2026
5245e3f
IONOS(build): update remote trigger job dependencies and conditions
printminion-co Jan 6, 2026
eec6a1d
IONOS(build): ensure remote trigger job always runs on push events
printminion-co Jan 7, 2026
667b7e6
IONOS(build): simplify remote trigger job dependencies and conditions
printminion-co Jan 7, 2026
c7866a4
IONOS(config): update submodule 84c33bb (feat: add configuration opti…
github-actions[bot] Jan 19, 2026
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
296 changes: 296 additions & 0 deletions .github/scripts/detect-app-cache.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,296 @@
#!/bin/bash

# SPDX-FileCopyrightText: 2025 STRATO AG
# SPDX-License-Identifier: AGPL-3.0-or-later

# Script to detect which apps need building vs. can be restored from cache
# Supports multiple cache sources: GitHub Actions cache and JFrog Artifactory
# Outputs JSON arrays for apps to build and apps to restore

set -e # Exit on error
set -u # Exit on undefined variable
set -o pipefail # Exit if any command in pipeline fails

# Required environment variables
: "${GH_TOKEN:?GH_TOKEN not set}"
: "${CACHE_VERSION:?CACHE_VERSION not set}"
: "${FORCE_REBUILD:?FORCE_REBUILD not set}"
: "${ARTIFACTORY_REPOSITORY_SNAPSHOT:?ARTIFACTORY_REPOSITORY_SNAPSHOT not set}"

# Optional JFrog variables
JF_URL="${JF_URL:-}"
JF_USER="${JF_USER:-}"
JF_ACCESS_TOKEN="${JF_ACCESS_TOKEN:-}"

# Input: MATRIX (JSON array of app configurations)
# Input: GITHUB_REF (current GitHub ref)
# Input: GITHUB_STEP_SUMMARY (path to step summary file)

# Outputs to $GITHUB_OUTPUT:
# - apps_to_build: JSON array of apps that need building
# - apps_to_restore: JSON array of apps that can be restored from cache
# - apps_sha_map: JSON object mapping app names to their SHAs
# - has_apps_to_build: boolean flag
# - has_apps_to_restore: boolean flag

echo "Collecting app SHAs and checking cache status..."
echo "Force rebuild mode: $FORCE_REBUILD"
echo ""

# Setup JFrog CLI if credentials are available
JFROG_AVAILABLE="false"
echo "=== JFrog Setup ==="
echo "JF_URL present: $([ -n "$JF_URL" ] && echo 'YES' || echo 'NO')"
echo "JF_USER present: $([ -n "$JF_USER" ] && echo 'YES' || echo 'NO')"
echo "JF_ACCESS_TOKEN present: $([ -n "$JF_ACCESS_TOKEN" ] && echo 'YES' || echo 'NO')"

if [ -n "$JF_URL" ] && [ -n "$JF_USER" ] && [ -n "$JF_ACCESS_TOKEN" ]; then
echo "✓ All JFrog credentials available"
echo "Installing JFrog CLI..."
# Install JFrog CLI
curl -fL https://install-cli.jfrog.io | sh
export PATH=$PATH:$PWD
echo "JFrog CLI version: $(jf --version)"

# Configure JFrog
echo "Configuring JFrog server: $JF_URL"
jf config add jfrog-server --url="$JF_URL" --user="$JF_USER" --access-token="$JF_ACCESS_TOKEN" --interactive=false

# Test connection with verbose output
echo "Testing JFrog connection..."
if jf rt ping; then
JFROG_AVAILABLE="true"
echo "✓ JFrog connection successful"
echo "Repository: $ARTIFACTORY_REPOSITORY_SNAPSHOT"
else
echo "⚠ JFrog ping failed, will fall back to GitHub cache"
echo "Ping output was unsuccessful"
fi
else
echo "⚠ JFrog credentials not available, using GitHub cache only"
[ -z "$JF_URL" ] && echo " - Missing: JF_URL"
[ -z "$JF_USER" ] && echo " - Missing: JF_USER"
[ -z "$JF_ACCESS_TOKEN" ] && echo " - Missing: JF_ACCESS_TOKEN"
fi
echo "JFROG_AVAILABLE=$JFROG_AVAILABLE"
echo "==================="
echo ""

# Get the matrix from input (passed as argument)
MATRIX="$1"

# Build JSON arrays for apps that need building/restoring
APPS_TO_BUILD="[]"
APPS_TO_RESTORE="[]"
APPS_CHECKED=0
APPS_CACHED=0
APPS_IN_JFROG=0
APPS_TO_BUILD_COUNT=0
APPS_TO_RESTORE_COUNT=0
APPS_SHA_MAP="{}"
echo ""

echo "### 📦 Cache Status Report for ($GITHUB_REF)" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
if [ "$FORCE_REBUILD" == "true" ]; then
echo "**🔄 FORCE REBUILD MODE ENABLED** - All caches bypassed" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
fi
if [ "$JFROG_AVAILABLE" == "true" ]; then
echo "**🎯 JFrog Artifact Cache**: Enabled for all branches" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
fi
echo "| App | SHA | Cache Key | Status |" >> "$GITHUB_STEP_SUMMARY"
echo "|-----|-----|-----------|--------|" >> "$GITHUB_STEP_SUMMARY"

# Iterate through each app in the matrix
while IFS= read -r app_json; do
APP_NAME=$(echo "$app_json" | jq -r '.name')
APP_PATH=$(echo "$app_json" | jq -r '.path')

APPS_CHECKED=$((APPS_CHECKED + 1))

# Get current submodule SHA
if [ -d "$APP_PATH" ]; then
CURRENT_SHA=$(git -C "$APP_PATH" rev-parse HEAD 2>/dev/null || echo "")
else
echo "⊘ $APP_NAME - directory not found, will build"
echo "| $APP_NAME | N/A | N/A | ⊘ Directory not found |" >> "$GITHUB_STEP_SUMMARY"
APPS_TO_BUILD=$(echo "$APPS_TO_BUILD" | jq -c --arg app "$APP_NAME" --arg sha "unknown" '. + [{name: $app, sha: $sha}]')
APPS_TO_BUILD_COUNT=$((APPS_TO_BUILD_COUNT + 1))
continue
fi

if [ -z "$CURRENT_SHA" ]; then
echo "⊘ $APP_NAME - not a git repo, will build"
echo "| $APP_NAME | N/A | N/A | ⊘ Not a git repo |" >> "$GITHUB_STEP_SUMMARY"
APPS_TO_BUILD=$(echo "$APPS_TO_BUILD" | jq -c --arg app "$APP_NAME" --arg sha "unknown" '. + [{name: $app, sha: $sha}]')
APPS_TO_BUILD_COUNT=$((APPS_TO_BUILD_COUNT + 1))
continue
fi

# Add SHA to the map for all apps (regardless of cache status)
APPS_SHA_MAP=$(echo "$APPS_SHA_MAP" | jq -c --arg app "$APP_NAME" --arg sha "$CURRENT_SHA" '.[$app] = $sha')

# Cache key that would be used for this app
# Format: <version>-app-build-<app-name>-<sha>
CACHE_KEY="${CACHE_VERSION}-app-build-${APP_NAME}-${CURRENT_SHA}"
SHORT_SHA="${CURRENT_SHA:0:8}"

echo -n " Checking $APP_NAME (SHA: $SHORT_SHA)... "

# If force rebuild is enabled, skip cache check and rebuild everything
if [ "$FORCE_REBUILD" == "true" ]; then
echo "🔄 force rebuild"
echo "| $APP_NAME | \`$SHORT_SHA\` | \`$CACHE_KEY\` | 🔄 Force rebuild |" >> "$GITHUB_STEP_SUMMARY"
APPS_TO_BUILD=$(echo "$APPS_TO_BUILD" | jq -c --arg app "$APP_NAME" --arg sha "$CURRENT_SHA" '. + [{name: $app, sha: $sha}]')
APPS_TO_BUILD_COUNT=$((APPS_TO_BUILD_COUNT + 1))
continue
fi

# Check JFrog first before GitHub cache (available for all branches)
if [ "$JFROG_AVAILABLE" == "true" ]; then
JFROG_PATH="${ARTIFACTORY_REPOSITORY_SNAPSHOT}/apps/${CACHE_VERSION}/${APP_NAME}/${APP_NAME}-${CURRENT_SHA}.tar.gz"

echo ""
echo " 🔍 Checking JFrog for $APP_NAME..."
echo " Path: $JFROG_PATH"
echo " Full SHA: $CURRENT_SHA"

# Check if artifact exists in JFrog with verbose output
echo " Running: jf rt s \"$JFROG_PATH\""
SEARCH_OUTPUT=$(jf rt s "$JFROG_PATH" 2>&1)
SEARCH_EXIT_CODE=$?

echo " Search exit code: $SEARCH_EXIT_CODE"
if [ $SEARCH_EXIT_CODE -eq 0 ]; then
echo " Search output:"
echo "$SEARCH_OUTPUT" | sed 's/^/ /'

if echo "$SEARCH_OUTPUT" | grep -q "$JFROG_PATH"; then
echo " ✓ Artifact found in JFrog!"
echo "✓ in JFrog"
echo "| $APP_NAME | \`$SHORT_SHA\` | \`$JFROG_PATH\` | 📦 In JFrog |" >> "$GITHUB_STEP_SUMMARY"
APPS_IN_JFROG=$((APPS_IN_JFROG + 1))
APPS_TO_RESTORE_COUNT=$((APPS_TO_RESTORE_COUNT + 1))
# Add to restore list with JFrog source
APPS_TO_RESTORE=$(echo "$APPS_TO_RESTORE" | jq -c --argjson app "$app_json" --arg sha "$CURRENT_SHA" --arg jfrog_path "$JFROG_PATH" --arg source "jfrog" '. + [($app + {sha: $sha, jfrog_path: $jfrog_path, source: $source})]')
continue
else
echo " ✗ Artifact not found in search results"
fi
else
echo " ✗ Search failed with error:"
echo "$SEARCH_OUTPUT" | sed 's/^/ /'
fi
echo " → Falling back to GitHub cache check"
fi

# Check if cache exists using GitHub CLI
# Include --ref to access caches from the current ref (branch, PR, etc.)
CACHE_EXISTS="false"
if ! CACHE_LIST=$(gh cache list --ref "$GITHUB_REF" --key "$CACHE_KEY" --json key --jq ".[].key" 2>&1); then
echo "⚠️ Warning: Failed to query cache for $APP_NAME: $CACHE_LIST"
echo "| $APP_NAME | \`$SHORT_SHA\` | \`$CACHE_KEY\` | ⚠️ Cache check failed - will build |" >> "$GITHUB_STEP_SUMMARY"
APPS_TO_BUILD=$(echo "$APPS_TO_BUILD" | jq -c --arg app "$APP_NAME" --arg sha "$CURRENT_SHA" '. + [{name: $app, sha: $sha}]')
APPS_TO_BUILD_COUNT=$((APPS_TO_BUILD_COUNT + 1))
continue
fi
if echo "$CACHE_LIST" | grep -q "^${CACHE_KEY}$"; then
CACHE_EXISTS="true"
APPS_CACHED=$((APPS_CACHED + 1))
APPS_TO_RESTORE_COUNT=$((APPS_TO_RESTORE_COUNT + 1))
echo "✓ cached"
echo "| $APP_NAME | \`$SHORT_SHA\` | \`$CACHE_KEY\` | ✅ Cached |" >> "$GITHUB_STEP_SUMMARY"
# Add to restore list with GitHub cache source
APPS_TO_RESTORE=$(echo "$APPS_TO_RESTORE" | jq -c --argjson app "$app_json" --arg sha "$CURRENT_SHA" --arg cache_key "$CACHE_KEY" --arg source "github-cache" '. + [($app + {sha: $sha, cache_key: $cache_key, source: $source})]')
else
echo "⚡ needs build"
echo "| $APP_NAME | \`$SHORT_SHA\` | \`$CACHE_KEY\` | 🔨 Needs build |" >> "$GITHUB_STEP_SUMMARY"
APPS_TO_BUILD=$(echo "$APPS_TO_BUILD" | jq -c --arg app "$APP_NAME" --arg sha "$CURRENT_SHA" '. + [{name: $app, sha: $sha}]')
APPS_TO_BUILD_COUNT=$((APPS_TO_BUILD_COUNT + 1))
fi

done < <(echo "$MATRIX" | jq -c '.[]')

echo "" >> "$GITHUB_STEP_SUMMARY"
echo "**Summary:**" >> "$GITHUB_STEP_SUMMARY"
echo "- Total apps checked: $APPS_CHECKED" >> "$GITHUB_STEP_SUMMARY"
echo "- 📦 Apps in JFrog: $APPS_IN_JFROG" >> "$GITHUB_STEP_SUMMARY"
echo "- ✅ Apps with cached builds: $APPS_CACHED" >> "$GITHUB_STEP_SUMMARY"
echo "- 🔨 Apps needing build: $APPS_TO_BUILD_COUNT" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"

TOTAL_AVAILABLE=$((APPS_IN_JFROG + APPS_CACHED))
if [ $TOTAL_AVAILABLE -gt 0 ] && [ $APPS_CHECKED -gt 0 ]; then
CACHE_HIT_PERCENT=$((TOTAL_AVAILABLE * 100 / APPS_CHECKED))
echo "**Cache hit rate: ${CACHE_HIT_PERCENT}%** 🎯" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
fi

echo ""
echo "Summary:"
echo " Total apps: $APPS_CHECKED"
echo " In JFrog: $APPS_IN_JFROG"
echo " Cached: $APPS_CACHED"
echo " To build: $APPS_TO_BUILD_COUNT"

# Validate no duplicate apps in build and restore lists
BUILD_APPS=$(echo "$APPS_TO_BUILD" | jq -r '.[].name' | sort)
RESTORE_APPS=$(echo "$APPS_TO_RESTORE" | jq -r '.[].name' | sort)
DUPLICATE_APPS=$(comm -12 <(echo "$BUILD_APPS") <(echo "$RESTORE_APPS"))

if [ -n "$DUPLICATE_APPS" ]; then
echo "ERROR: Apps appear in both build and restore lists:"
echo "$DUPLICATE_APPS"
exit 1
fi

# Validate that we built valid JSON
if ! echo "$APPS_TO_BUILD" | jq empty 2>/dev/null; then
echo "ERROR: Failed to build valid JSON for apps_to_build"
echo "Content: $APPS_TO_BUILD"
exit 1
fi

if ! echo "$APPS_TO_RESTORE" | jq empty 2>/dev/null; then
echo "ERROR: Failed to build valid JSON for apps_to_restore"
echo "Content: $APPS_TO_RESTORE"
exit 1
fi

# Output app list with SHAs for the build job to use
# Use proper multiline output format for GitHub Actions
echo "apps_to_build<<APPS_TO_BUILD_JSON_EOF" >> "$GITHUB_OUTPUT"
echo "$APPS_TO_BUILD" >> "$GITHUB_OUTPUT"
echo "APPS_TO_BUILD_JSON_EOF" >> "$GITHUB_OUTPUT"

# Output the unified list of apps to restore (from either GitHub cache or JFrog)
echo "apps_to_restore<<APPS_TO_RESTORE_JSON_EOF" >> "$GITHUB_OUTPUT"
echo "$APPS_TO_RESTORE" >> "$GITHUB_OUTPUT"
echo "APPS_TO_RESTORE_JSON_EOF" >> "$GITHUB_OUTPUT"

# Output the SHA map for all apps
echo "apps_sha_map<<APPS_SHA_MAP_JSON_EOF" >> "$GITHUB_OUTPUT"
echo "$APPS_SHA_MAP" >> "$GITHUB_OUTPUT"
echo "APPS_SHA_MAP_JSON_EOF" >> "$GITHUB_OUTPUT"

# Output flags for conditional job execution
if [ $APPS_TO_BUILD_COUNT -gt 0 ]; then
echo "has_apps_to_build=true" >> "$GITHUB_OUTPUT"
else
echo "has_apps_to_build=false" >> "$GITHUB_OUTPUT"
fi

if [ $APPS_TO_RESTORE_COUNT -gt 0 ]; then
echo "has_apps_to_restore=true" >> "$GITHUB_OUTPUT"
else
echo "has_apps_to_restore=false" >> "$GITHUB_OUTPUT"
fi

echo ""
if [ $APPS_TO_BUILD_COUNT -eq 0 ]; then
echo "🎉 All apps are cached! No builds needed."
else
echo "✓ Will build $APPS_TO_BUILD_COUNT app(s)"
fi
Loading
Loading