diff --git a/.github/workflows/build-artifact.yml b/.github/workflows/build-artifact.yml index e2d061bce774f..91cafc4a410dd 100644 --- a/.github/workflows/build-artifact.yml +++ b/.github/workflows/build-artifact.yml @@ -50,24 +50,33 @@ jobs: outputs: external-apps-matrix: ${{ steps.set-matrix.outputs.matrix }} steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + submodules: true + fetch-depth: '1' + + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y make jq + - name: Set matrix id: set-matrix run: | # Create matrix configuration as a compact JSON string matrix='[ { - "name": "richdocuments", - "path": "apps-external/richdocuments", + "name": "activity", + "path": "apps-external/activity", "has_npm": true, "has_composer": true, - "makefile_target": "build_richdocuments_app" + "makefile_target": "build_activity_app" }, { - "name": "viewer", - "path": "apps-external/viewer", + "name": "assistant", + "path": "apps-external/assistant", "has_npm": true, "has_composer": true, - "makefile_target": "build_viewer_app" + "makefile_target": "build_assistant_app" }, { "name": "calendar", @@ -77,11 +86,18 @@ jobs: "makefile_target": "build_calendar_app" }, { - "name": "activity", - "path": "apps-external/activity", + "name": "circles", + "path": "apps-external/circles", + "has_npm": false, + "has_composer": true, + "makefile_target": "build_circles_app" + }, + { + "name": "collectives", + "path": "apps-external/collectives", "has_npm": true, "has_composer": true, - "makefile_target": "build_activity_app" + "makefile_target": "build_collectives_app" }, { "name": "contacts", @@ -91,46 +107,39 @@ jobs: "makefile_target": "build_contacts_app" }, { - "name": "collectives", - "path": "apps-external/collectives", + "name": "deck", + "path": "apps-external/deck", "has_npm": true, "has_composer": true, - "makefile_target": "build_collectives_app" - }, - { - "name": "circles", - "path": "apps-external/circles", - "has_npm": false, - "has_composer": true, - "makefile_target": "build_circles_app" + "makefile_target": "build_deck_app" }, { - "name": "notifications", - "path": "apps-external/notifications", + "name": "end_to_end_encryption", + "path": "apps-external/end_to_end_encryption", "has_npm": true, "has_composer": true, - "makefile_target": "build_notifications_app" + "makefile_target": "build_end_to_end_encryption_app" }, { - "name": "notify_push", - "path": "apps-external/notify_push", - "has_npm": false, + "name": "forms", + "path": "apps-external/forms", + "has_npm": true, "has_composer": true, - "makefile_target": "build_notify_push_app" + "makefile_target": "build_forms_app" }, { - "name": "tasks", - "path": "apps-external/tasks", + "name": "groupfolders", + "path": "apps-external/groupfolders", "has_npm": true, "has_composer": true, - "makefile_target": "build_tasks_app" + "makefile_target": "build_groupfolders_app" }, { - "name": "spreed", - "path": "apps-external/spreed", + "name": "integration_openai", + "path": "apps-external/integration_openai", "has_npm": true, "has_composer": true, - "makefile_target": "build_spreed_app" + "makefile_target": "build_integration_openai_app" }, { "name": "mail", @@ -149,7 +158,7 @@ jobs: { "name": "ncw_mailtemplate", "path": "apps-external/ncw_mailtemplate", - "has_npm": false, + "has_npm": true, "has_composer": true, "makefile_target": "build_ncw_mailtemplate_app" }, @@ -161,32 +170,32 @@ jobs: "makefile_target": "build_notes_app" }, { - "name": "groupfolders", - "path": "apps-external/groupfolders", + "name": "notifications", + "path": "apps-external/notifications", "has_npm": true, "has_composer": true, - "makefile_target": "build_groupfolders_app" + "makefile_target": "build_notifications_app" }, { - "name": "deck", - "path": "apps-external/deck", - "has_npm": true, + "name": "notify_push", + "path": "apps-external/notify_push", + "has_npm": false, "has_composer": true, - "makefile_target": "build_deck_app" + "makefile_target": "build_notify_push_app" }, { - "name": "end_to_end_encryption", - "path": "apps-external/end_to_end_encryption", + "name": "richdocuments", + "path": "apps-external/richdocuments", "has_npm": true, "has_composer": true, - "makefile_target": "build_end_to_end_encryption_app" + "makefile_target": "build_richdocuments_app" }, { - "name": "forms", - "path": "apps-external/forms", + "name": "spreed", + "path": "apps-external/spreed", "has_npm": true, "has_composer": true, - "makefile_target": "build_forms_app" + "makefile_target": "build_spreed_app" }, { "name": "tables", @@ -195,6 +204,13 @@ jobs: "has_composer": true, "makefile_target": "build_tables_app" }, + { + "name": "tasks", + "path": "apps-external/tasks", + "has_npm": true, + "has_composer": true, + "makefile_target": "build_tasks_app" + }, { "name": "text", "path": "apps-external/text", @@ -217,25 +233,18 @@ jobs: "makefile_target": "build_user_oidc_app" }, { - "name": "whiteboard", - "path": "apps-external/whiteboard", - "has_npm": true, - "has_composer": true, - "makefile_target": "build_whiteboard_app" - }, - { - "name": "assistant", - "path": "apps-external/assistant", + "name": "viewer", + "path": "apps-external/viewer", "has_npm": true, "has_composer": true, - "makefile_target": "build_assistant_app" + "makefile_target": "build_viewer_app" }, { - "name": "integration_openai", - "path": "apps-external/integration_openai", + "name": "whiteboard", + "path": "apps-external/whiteboard", "has_npm": true, "has_composer": true, - "makefile_target": "build_integration_openai_app" + "makefile_target": "build_whiteboard_app" } ]' @@ -248,6 +257,254 @@ jobs: exit 1 fi + - name: Validate matrix against Makefile + run: | + set +e # Intentionally allow script to continue on error for custom error handling and reporting to GITHUB_STEP_SUMMARY + set -u # Exit on undefined variable + + echo "### 🔍 Matrix Validation" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + # Debug: Check if apps-external exists + echo "Checking apps-external directory..." + if [ ! -d "apps-external" ]; then + echo "❌ **Error:** apps-external directory does not exist!" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "Directory listing:" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + ls -la >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + exit 1 + fi + + echo "Apps-external directory exists. Listing contents:" + ls -la apps-external/ | head -10 + + # Check if jq is available + echo "Checking if jq is installed..." + if ! command -v jq &> /dev/null; then + echo "❌ **Error:** jq is not installed!" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "jq is required for matrix generation but was not found in PATH." >> $GITHUB_STEP_SUMMARY + exit 1 + fi + echo "jq version: $(jq --version)" + + echo "Generating matrix from Makefile..." + # Capture both stdout and stderr separately to better diagnose issues + makefile_output=$(make -f IONOS/Makefile generate_external_apps_matrix_json 2>&1) + makefile_exit_code=$? + + echo "Makefile exit code: ${makefile_exit_code}" + echo "Makefile output length: ${#makefile_output}" + + # Debug: Check if GITHUB_STEP_SUMMARY is set + echo "GITHUB_STEP_SUMMARY: ${GITHUB_STEP_SUMMARY:-NOT SET}" + + # If the Makefile command failed, show the error + if [ ${makefile_exit_code} -ne 0 ]; then + echo "" + echo "=== MAKEFILE ERROR ===" + echo "Exit code: ${makefile_exit_code}" + echo "Output:" + echo "$makefile_output" + echo "=====================" + echo "" + + # Write to summary + echo "❌ **Error:** Makefile command failed with exit code ${makefile_exit_code}" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "
" >> $GITHUB_STEP_SUMMARY + echo "Makefile error output" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + echo "$makefile_output" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + echo "
" >> $GITHUB_STEP_SUMMARY + + echo "Error written to summary file: ${GITHUB_STEP_SUMMARY}" + exit 1 + fi + + # Filter out the info message to get just the JSON + # The Makefile outputs "[i] Generating..." to stderr, but we captured everything with 2>&1 + # So we need to extract just the JSON part + generated_matrix=$(echo "$makefile_output" | grep -v '^\[i\]' || echo "$makefile_output") + + workflow_matrix='${{ steps.set-matrix.outputs.matrix }}' + + # Debug output + echo "Generated matrix length: ${#generated_matrix}" + echo "Workflow matrix length: ${#workflow_matrix}" + + # Show first 200 chars of generated matrix for debugging + if [ -n "$generated_matrix" ]; then + echo "Generated matrix preview: ${generated_matrix:0:200}..." + fi + + # Validate that we got valid JSON + if ! echo "$generated_matrix" | jq empty 2>/dev/null; then + echo "❌ **Error:** Generated matrix is not valid JSON" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "
" >> $GITHUB_STEP_SUMMARY + echo "Invalid JSON output" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + echo "$generated_matrix" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + echo "
" >> $GITHUB_STEP_SUMMARY + exit 1 + fi + + # Validate that we got data + if [ -z "$generated_matrix" ] || [ -z "$workflow_matrix" ]; then + echo "❌ **Error:** Failed to load matrices" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- Generated matrix empty: $([ -z "$generated_matrix" ] && echo "yes" || echo "no")" >> $GITHUB_STEP_SUMMARY + echo "- Workflow matrix empty: $([ -z "$workflow_matrix" ] && echo "yes" || echo "no")" >> $GITHUB_STEP_SUMMARY + echo "- Makefile exit code: ${makefile_exit_code}" >> $GITHUB_STEP_SUMMARY + + exit 1 + fi + + # Sort both matrices for comparison + generated_sorted=$(echo "$generated_matrix" | jq -S '.' 2>&1 || echo "ERROR") + workflow_sorted=$(echo "$workflow_matrix" | jq -S '.' 2>&1 || echo "ERROR") + + echo "Sorted matrix lengths - generated: ${#generated_sorted}, workflow: ${#workflow_sorted}" + + # Compare the two matrices + if [ "$generated_sorted" = "$workflow_sorted" ]; then + echo "✅ **Validation passed!** The workflow matrix matches the Makefile configuration." >> $GITHUB_STEP_SUMMARY + echo "" + echo "✅ Matrix validation passed!" + else + echo "❌ **Validation failed!** The workflow matrix does not match the Makefile configuration." >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + echo "Starting detailed comparison..." + + # Extract app names from both matrices + generated_apps=$(echo "$generated_matrix" | jq -r '.[].name' 2>/dev/null | sort || echo "") + workflow_apps=$(echo "$workflow_matrix" | jq -r '.[].name' 2>/dev/null | sort || echo "") + + echo "Generated apps count: $(echo "$generated_apps" | wc -l)" + echo "Workflow apps count: $(echo "$workflow_apps" | wc -l)" + + # Find missing apps (in Makefile but not in workflow) + missing_apps=$(comm -23 <(echo "$generated_apps") <(echo "$workflow_apps")) + if [ $? -ne 0 ]; then + echo "Error: comm command failed when finding missing apps." >&2 + exit 1 + fi + # Find extra apps (in workflow but not in Makefile) + extra_apps=$(comm -13 <(echo "$generated_apps") <(echo "$workflow_apps")) + if [ $? -ne 0 ]; then + echo "Error: comm command failed when finding extra apps." >&2 + exit 1 + fi + + echo "Missing apps: ${missing_apps:-none}" + echo "Extra apps: ${extra_apps:-none}" + + if [ -n "$missing_apps" ]; then + echo "#### ⚠️ Missing Apps" >> $GITHUB_STEP_SUMMARY + echo "The following apps are configured in the Makefile but missing from the workflow:" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + echo "$missing_apps" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + fi + + if [ -n "$extra_apps" ]; then + echo "#### ⚠️ Extra Apps" >> $GITHUB_STEP_SUMMARY + echo "The following apps are in the workflow but not configured in the Makefile:" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + echo "$extra_apps" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + fi + + # Check for configuration mismatches in common apps + common_apps=$(comm -12 <(echo "$generated_apps") <(echo "$workflow_apps") 2>/dev/null || echo "") + + echo "Common apps count: $(echo "$common_apps" | wc -l)" + + if [ -n "$common_apps" ]; then + mismatched_apps="" + + while IFS= read -r app; do + [ -z "$app" ] && continue + gen_config=$(echo "$generated_matrix" | jq -c --arg app "$app" '.[] | select(.name == $app)' 2>/dev/null || echo "") + wf_config=$(echo "$workflow_matrix" | jq -c --arg app "$app" '.[] | select(.name == $app)' 2>/dev/null || echo "") + + if [ -n "$gen_config" ] && [ -n "$wf_config" ] && [ "$gen_config" != "$wf_config" ]; then + mismatched_apps="${mismatched_apps}${app}"$'\n' + fi + done <<< "$common_apps" + + echo "Mismatched apps: ${mismatched_apps:-none}" + + if [ -n "$mismatched_apps" ]; then + echo "#### ⚠️ Configuration Mismatches" >> $GITHUB_STEP_SUMMARY + echo "The following apps have different configurations (has_npm, has_composer, etc.):" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + echo "$mismatched_apps" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "
" >> $GITHUB_STEP_SUMMARY + echo "📋 Detailed differences" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo '```diff' >> $GITHUB_STEP_SUMMARY + + while IFS= read -r app; do + [ -z "$app" ] && continue + echo "=== $app ===" >> $GITHUB_STEP_SUMMARY + diff -u --label "Workflow" --label "Makefile" \ + <(echo "$workflow_matrix" | jq --arg app "$app" '.[] | select(.name == $app)' 2>/dev/null || echo "{}") \ + <(echo "$generated_matrix" | jq --arg app "$app" '.[] | select(.name == $app)' 2>/dev/null || echo "{}") \ + >> $GITHUB_STEP_SUMMARY 2>&1 || true + done <<< "$mismatched_apps" + + echo '```' >> $GITHUB_STEP_SUMMARY + echo "
" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + fi + fi + + # Provide fix instructions + echo "#### 🔧 How to Fix" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "Run this command locally to generate the correct matrix:" >> $GITHUB_STEP_SUMMARY + echo '```bash' >> $GITHUB_STEP_SUMMARY + echo "make -f IONOS/Makefile generate_external_apps_matrix_json" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "Then update the \`matrix\` variable in \`.github/workflows/build-artifact.yml\` in the set-matrix step with the generated output." >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + # Show full diff in expandable section + echo "
" >> $GITHUB_STEP_SUMMARY + echo "📄 Full matrix comparison" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Workflow Matrix:**" >> $GITHUB_STEP_SUMMARY + echo '```json' >> $GITHUB_STEP_SUMMARY + echo "$workflow_matrix" | jq '.' 2>/dev/null >> $GITHUB_STEP_SUMMARY || echo "$workflow_matrix" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Makefile Matrix:**" >> $GITHUB_STEP_SUMMARY + echo '```json' >> $GITHUB_STEP_SUMMARY + echo "$generated_matrix" | jq '.' 2>/dev/null >> $GITHUB_STEP_SUMMARY || echo "$generated_matrix" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + echo "
" >> $GITHUB_STEP_SUMMARY + + echo "" + echo "❌ ERROR: Matrix validation failed!" + echo "See the job summary for details on what's wrong and how to fix it." + echo "Summary file size: $(wc -c < $GITHUB_STEP_SUMMARY || echo 0) bytes" + exit 1 + fi + build-external-apps: runs-on: ubuntu-latest needs: prepare-matrix diff --git a/IONOS b/IONOS index 1395a7b445f24..945436e81cf68 160000 --- a/IONOS +++ b/IONOS @@ -1 +1 @@ -Subproject commit 1395a7b445f249ddec09400ded344de22af58d7b +Subproject commit 945436e81cf68f8d4080641124ac9620adf46fe8