mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 01:18:42 +00:00
This pull request improves the robustness and reliability of the script and workflows that detect changed or new maintained apps in pull requests. The main focus is on making the detection script pass validation when the test is triggered but no new FMAs are detected. **Script robustness and error handling:** * The `.github/scripts/detect-new-fmas-in-pr.sh` script is updated to always exit successfully (status 0) when no changes are detected, and only exit with error (status 1) for critical failures like missing `jq`. A new `safe_exit` function is introduced to standardize output and ensure graceful exits. [[1]](diffhunk://#diff-f9bbb0340f504713c99d610f3c64bf281fc13ed3cb8a1c06a5366272c9828a8dR7-R11) [[2]](diffhunk://#diff-f9bbb0340f504713c99d610f3c64bf281fc13ed3cb8a1c06a5366272c9828a8dL21-R39) * Improved error handling for missing files, empty variables, and failed commands throughout the script, including handling cases where `merge-base`, `git show`, or `jq` fail, and ensuring empty or missing data does not cause the script to error out. [[1]](diffhunk://#diff-f9bbb0340f504713c99d610f3c64bf281fc13ed3cb8a1c06a5366272c9828a8dL32-R66) [[2]](diffhunk://#diff-f9bbb0340f504713c99d610f3c64bf281fc13ed3cb8a1c06a5366272c9828a8dR87-R108) [[3]](diffhunk://#diff-f9bbb0340f504713c99d610f3c64bf281fc13ed3cb8a1c06a5366272c9828a8dL75-R155) **Workflow improvements:** * The `test-fma-darwin-pr-only.yml` and `test-fma-windows-pr-only.yml` workflows are updated to default to "no changes" if the detection step fails or does not set the expected output, preventing false positives or workflow failures. [[1]](diffhunk://#diff-28b30c8601cb7662d59efbfbbcf800cae91455fd3d875627659dced8c1257a24L70-R72) [[2]](diffhunk://#diff-51641fd1d2cc19348b81fd8310b62ad270ca5082ceddff2d49064e78f126a1eaL76-R78)
157 lines
5.2 KiB
Bash
Executable file
157 lines
5.2 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
# Script to detect changed/new maintained apps in a PR
|
|
# This script compares the PR branch with the base branch to find:
|
|
# 1. New apps added to apps.json
|
|
# 2. Apps with changed manifest files
|
|
#
|
|
# This script always exits successfully (0) when no changes are detected.
|
|
# It only exits with error (1) for critical failures like missing jq.
|
|
|
|
set -uo pipefail
|
|
|
|
# Get repository root
|
|
REPO_ROOT="${GITHUB_WORKSPACE:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
|
|
APPS_JSON="${REPO_ROOT}/ee/maintained-apps/outputs/apps.json"
|
|
OUTPUTS_DIR="${REPO_ROOT}/ee/maintained-apps/outputs"
|
|
|
|
# Base branch (usually main or the PR's base branch)
|
|
# In GitHub Actions, GITHUB_BASE_REF is set for pull_request events
|
|
BASE_BRANCH="${GITHUB_BASE_REF:-main}"
|
|
# Use origin/ prefix for remote branch reference
|
|
BASE_BRANCH_REF="origin/${BASE_BRANCH}"
|
|
|
|
# Ensure GITHUB_OUTPUT exists
|
|
GITHUB_OUTPUT="${GITHUB_OUTPUT:-${REPO_ROOT}/.github_output}"
|
|
|
|
# Function to safely set outputs and exit
|
|
safe_exit() {
|
|
local has_changes="${1:-false}"
|
|
local changed_apps="${2:-[]}"
|
|
echo "CHANGED_APPS=${changed_apps}" >> "$GITHUB_OUTPUT"
|
|
echo "HAS_CHANGES=${has_changes}" >> "$GITHUB_OUTPUT"
|
|
exit 0
|
|
}
|
|
|
|
# Check if jq is available - this is a critical failure
|
|
if ! command -v jq &> /dev/null; then
|
|
echo "Error: jq is required but not installed" >&2
|
|
safe_exit "false" "[]"
|
|
exit 1
|
|
fi
|
|
|
|
# Function to extract app slugs from apps.json
|
|
extract_slugs() {
|
|
local apps_file="$1"
|
|
if [ ! -f "$apps_file" ]; then
|
|
echo ""
|
|
return 0
|
|
fi
|
|
jq -r '.apps[].slug' "$apps_file" 2>/dev/null | sort || echo ""
|
|
}
|
|
|
|
# Function to extract app slugs from changed manifest files
|
|
extract_slugs_from_changed_manifests() {
|
|
local changed_files="$1"
|
|
local slugs=()
|
|
|
|
if [ -z "$changed_files" ]; then
|
|
echo ""
|
|
return 0
|
|
fi
|
|
|
|
while IFS= read -r file; do
|
|
# Skip empty lines
|
|
[ -z "$file" ] && continue
|
|
|
|
# Extract slug from path like: outputs/app-name/darwin.json or outputs/app-name/windows.json
|
|
if [[ "$file" =~ outputs/([^/]+)/(darwin|windows)\.json$ ]]; then
|
|
app_name="${BASH_REMATCH[1]}"
|
|
platform="${BASH_REMATCH[2]}"
|
|
slug="${app_name}/${platform}"
|
|
slugs+=("$slug")
|
|
fi
|
|
done <<< "$changed_files"
|
|
|
|
# Remove duplicates and sort
|
|
if [ ${#slugs[@]} -eq 0 ]; then
|
|
echo ""
|
|
else
|
|
printf '%s\n' "${slugs[@]}" | sort -u
|
|
fi
|
|
}
|
|
|
|
# Get changed files in outputs directory
|
|
echo "Detecting changed files in outputs directory..."
|
|
echo "Comparing HEAD with ${BASE_BRANCH_REF}..."
|
|
|
|
# Use merge-base to find the common ancestor for comparison
|
|
# If merge-base fails, try using the base branch ref directly
|
|
MERGE_BASE=""
|
|
if git merge-base "${BASE_BRANCH_REF}" HEAD &>/dev/null; then
|
|
MERGE_BASE=$(git merge-base "${BASE_BRANCH_REF}" HEAD 2>/dev/null || echo "")
|
|
fi
|
|
|
|
# If merge-base still failed, try the base branch ref directly
|
|
if [ -z "$MERGE_BASE" ]; then
|
|
echo "Warning: Could not find merge-base, using ${BASE_BRANCH_REF} directly"
|
|
MERGE_BASE="${BASE_BRANCH_REF}"
|
|
fi
|
|
|
|
# Get changed files, handling errors gracefully
|
|
CHANGED_FILES=""
|
|
if git diff --name-only "$MERGE_BASE" HEAD -- "ee/maintained-apps/outputs/" &>/dev/null; then
|
|
CHANGED_FILES=$(git diff --name-only "$MERGE_BASE" HEAD -- "ee/maintained-apps/outputs/" 2>/dev/null || echo "")
|
|
else
|
|
echo "Warning: Could not get changed files, assuming no changes"
|
|
CHANGED_FILES=""
|
|
fi
|
|
|
|
# Extract slugs from changed manifest files
|
|
CHANGED_MANIFEST_SLUGS=$(extract_slugs_from_changed_manifests "$CHANGED_FILES")
|
|
|
|
# Get current apps.json slugs
|
|
CURRENT_SLUGS=$(extract_slugs "$APPS_JSON")
|
|
|
|
# Get base branch apps.json slugs
|
|
echo "Fetching base branch apps.json from ${MERGE_BASE}..."
|
|
BASE_APPS_JSON=""
|
|
BASE_SLUGS=""
|
|
if git show "${MERGE_BASE}:ee/maintained-apps/outputs/apps.json" &>/dev/null; then
|
|
BASE_APPS_JSON=$(git show "${MERGE_BASE}:ee/maintained-apps/outputs/apps.json" 2>/dev/null || echo "")
|
|
if [ -n "$BASE_APPS_JSON" ]; then
|
|
BASE_SLUGS=$(echo "$BASE_APPS_JSON" | jq -r '.apps[].slug' 2>/dev/null | sort || echo "")
|
|
fi
|
|
fi
|
|
|
|
if [ -z "$BASE_SLUGS" ]; then
|
|
echo "Warning: Could not find apps.json in base branch, only checking manifest file changes"
|
|
# If we can't get base slugs, only use manifest changes (don't assume all apps are new)
|
|
NEW_SLUGS=""
|
|
else
|
|
# Find new slugs in apps.json
|
|
NEW_SLUGS=$(comm -13 <(echo "$BASE_SLUGS" || echo "") <(echo "$CURRENT_SLUGS" || echo "") 2>/dev/null || echo "")
|
|
fi
|
|
|
|
# Combine all changed slugs (from manifest changes and new apps)
|
|
ALL_CHANGED_SLUGS=$(printf '%s\n' "$CHANGED_MANIFEST_SLUGS" "$NEW_SLUGS" | grep -v '^$' | sort -u || echo "")
|
|
|
|
# Output results - always exit successfully
|
|
if [ -z "$ALL_CHANGED_SLUGS" ]; then
|
|
echo "No changed apps detected."
|
|
safe_exit "false" "[]"
|
|
fi
|
|
|
|
echo "Detected changed apps:"
|
|
echo "$ALL_CHANGED_SLUGS" | while read -r slug; do
|
|
[ -n "$slug" ] && echo " - $slug"
|
|
done
|
|
|
|
# Output as JSON array for GitHub Actions
|
|
CHANGED_APPS_JSON=$(echo "$ALL_CHANGED_SLUGS" | jq -R -s -c 'split("\n") | map(select(length > 0))' 2>/dev/null || echo "[]")
|
|
|
|
echo "CHANGED_APPS=$CHANGED_APPS_JSON" >> "$GITHUB_OUTPUT"
|
|
echo "HAS_CHANGES=true" >> "$GITHUB_OUTPUT"
|
|
exit 0
|
|
|
|
|