Skip to content
Merged

nsw-2 #170

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
5747835
IONOS(theming): fix user bubble color
bromiesTM Nov 6, 2025
0cffad2
IONOS(theming): adjust tasks app theming
bromiesTM Nov 6, 2025
615f9e5
IONOS(mail): update submodule to hide new mail creation for existing …
seriAlizations Nov 13, 2025
12ed8ca
IONOS(theming): improve app manager colors
bromiesTM Nov 6, 2025
be48894
IONOS(theming): improve chat app colors
bromiesTM Nov 6, 2025
ef9f9ed
IONOS(theming): fix search button hover color
bromiesTM Nov 10, 2025
39abccd
IONOS(theming): fix search menu darkmode color
bromiesTM Nov 10, 2025
a41d95e
IONOS(theming): adjust colors for calendar app
bromiesTM Nov 10, 2025
962d778
IONOS(theming): load all css files from theme folder
bromiesTM Nov 10, 2025
c7d378f
IONOS(theming): adjust profile app colors
bromiesTM Nov 10, 2025
70e171e
IONOS(theming): fix assistant navigation text color
bromiesTM Nov 10, 2025
af1c348
IONOS(theming): fix notification settings colors
bromiesTM Nov 10, 2025
bf50cae
IONOS(theming): fix notes suggestion colors
bromiesTM Nov 12, 2025
abe24a2
IONOS(theming): fix tables app colors
bromiesTM Nov 12, 2025
c5ff566
IONOS(theming): rename css variable to reflect broader usage
bromiesTM Nov 12, 2025
54cd65b
IONOS(theming): fix missing hover color for secondary button
bromiesTM Nov 20, 2025
c73c2d3
IONOS(theming): make user bubble visible everywhere
bromiesTM Nov 20, 2025
ca7fa1f
IONOS(theming): invert activity timeline icons in darkmode
bromiesTM Nov 20, 2025
430a195
IONOS(theming/deck): fix icon hover color
bromiesTM Nov 20, 2025
980c3c4
IONOS(build): sort build targets for external apps
printminion-co Nov 10, 2025
e68efdb
IONOS(build): fixup build artifact file matrix for external apps
Arsalanulhaq Nov 21, 2025
321466e
IONOS(theming): load all css files from theme folder
bromiesTM Nov 10, 2025
7e3e151
IONOS(theming): fix collabora vertical shift and copilot suggestion f…
seriAlizations Nov 13, 2025
c3099ee
IONOS(ncw_mailtemplate): update submodule (fix broken mails)
bromiesTM Dec 3, 2025
3e3dc12
IONOS(theming): fix text editor background color
bromiesTM Dec 4, 2025
5f04017
IONOS(AppsMenu): update submodule (fixed styling)
bromiesTM Dec 8, 2025
67a8d87
IONOS(theming): use static favicon in all apps for consistent branding
tanyaka Dec 8, 2025
ebf75e8
IONOS(theming): fix file viewer background color
tanyaka Dec 9, 2025
d58d8ff
IONOS(ncw_mailtemplate) update submodule (adjust mail styling)
bromiesTM Dec 10, 2025
e7053d8
IONOS(theming): fix breadcrumb button size
bromiesTM Dec 8, 2025
e27d7d1
IONOS(theming): change target dialog button colors
bromiesTM Dec 8, 2025
8986050
IONOS(tests): add tests for developer documentation link generation
Arsalanulhaq Dec 2, 2025
b671096
IONOS(appsettings): conditionally display developer documentation lin…
Arsalanulhaq Dec 2, 2025
b20dd9f
IONOS(config): add developer_documentation_url boolean and build ncw …
Arsalanulhaq Dec 15, 2025
67dbbac
IONOS(theming): fix table entry edit button colors
bromiesTM Dec 8, 2025
00dee1b
IONOS(theming): add missing color definition for --ion-color-cool-gre…
tanyaka Dec 11, 2025
5602edc
IONOS(theming): tables app: refine table header and editor styles for…
tanyaka Dec 11, 2025
40d946f
IONOS(theming): adjust position of grid button in file list
Arsalanulhaq Dec 11, 2025
a7f1aa7
IONOS(build): copy build-artifact.yml as build-artifact-original.yml
printminion-co Nov 12, 2025
1e9a82f
IONOS(build): update artifact filename to include '-original' suffix
printminion-co Nov 12, 2025
696c05f
IONOS(build): update fetch-depth in build-artifact.yml to integer format
printminion-co Nov 12, 2025
dddc2e9
IONOS(build): update action versions for improved functionality and c…
printminion-co Nov 12, 2025
0ff91ac
IONOS(build): add retry logic for GitLab pipeline trigger
printminion-co Nov 12, 2025
df71407
IONOS(build): add retry logic for artifact upload in build-artifact.yml
printminion-co Nov 12, 2025
c941256
IONOS(build): fix step ID naming in build-artifact.yml for consistency
printminion-co Nov 12, 2025
a4d2211
IONOS(build): generate apps matrix dynamically from Makefile
printminion-co Nov 12, 2025
0603f90
IONOS(build): optimize build workflow - only rebuild changed apps
printminion-co Nov 11, 2025
ed2b434
IONOS(build): ensure jobs depend on successful matrix preparation
printminion-co Nov 12, 2025
f3a9c44
IONOS(build): add manual trigger for comparison testing in build-arti…
printminion-co Nov 13, 2025
807f01c
IONOS(ci): Add app cache detection for JFrog build pipeline
bromiesTM Dec 15, 2025
9a7f678
IONOS(ci): Refactor cache detection logic into separate script
bromiesTM Dec 15, 2025
9500438
IONOS(ci): use cache version env for jfrog invalidation
bromiesTM Dec 17, 2025
94e7ed3
IONOS(ci): fix typos and spacing
bromiesTM Dec 17, 2025
2b62b44
IONOS(theming): fix themefolder settings dropdown colors
bromiesTM Dec 15, 2025
71ecc37
IONOS(Theming): fix the background color in darkmode
tanyaka Dec 17, 2025
a9c4391
IONOS(theming): update checkbox-radio-switch styles for better visibi…
Arsalanulhaq Dec 16, 2025
4c2f17d
fix(comments): Check comment object
nickvergessen Dec 11, 2025
8dfb295
fix(NewUserDialog): allow to deselect a group from the list
Antreesy Oct 23, 2025
aaf5824
IONOS(NewUserDialog): update group options to exclude admin from sub-…
Arsalanulhaq Dec 23, 2025
179574c
IONOS(build): add ping step for JFrog server in build-artifact.yml
printminion-co Dec 22, 2025
1143f3e
IONOS(theming): fix secondary button background color hover state
printminion-co Jan 5, 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