Generate README #1591
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # yamllint disable rule:line-length | |
| --- | |
| name: Generate README | |
| on: | |
| schedule: | |
| - cron: 0 17 * * * | |
| workflow_dispatch: null | |
| jobs: | |
| README_updater: | |
| if: github.repository_owner == 'alexbelgium' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout Repo | |
| uses: actions/checkout@v6 | |
| - name: Install jq + yq (v4) | |
| run: | | |
| set -euo pipefail | |
| if ! command -v jq >/dev/null 2>&1; then | |
| sudo apt-get update -y | |
| sudo apt-get install -y jq | |
| fi | |
| if ! command -v yq >/dev/null 2>&1; then | |
| sudo wget -qO /usr/local/bin/yq "https://github.com/mikefarah/yq/releases/download/v4.44.3/yq_linux_amd64" | |
| sudo chmod +x /usr/local/bin/yq | |
| fi | |
| - name: Create README file | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| echo "Starting" | |
| # --------------------------- | |
| # Helper functions (JSON/YAML) | |
| # --------------------------- | |
| get_config() { | |
| # Echos "<path>|<type>" where type is json|yaml, or "|" if none found | |
| local dir="$1" | |
| if [ -f "$dir/config.json" ]; then | |
| echo "$dir/config.json|json" | |
| elif [ -f "$dir/config.yaml" ]; then | |
| echo "$dir/config.yaml|yaml" | |
| elif [ -f "$dir/config.yml" ]; then | |
| echo "$dir/config.yml|yaml" | |
| else | |
| echo "|" | |
| fi | |
| } | |
| get_raw() { | |
| # Print raw scalar or list items (newline-separated) | |
| # $1 = jq/yq expr, $2 = type (json|yaml), $3 = path | |
| local expr="$1" type="$2" file="$3" | |
| if [ "$type" = "json" ]; then | |
| jq -r "$expr" "$file" 2>/dev/null || true | |
| else | |
| yq -r "$expr" "$file" 2>/dev/null || true | |
| fi | |
| } | |
| get_jsonc() { | |
| # Print compact JSON form of a subnode (for substring checks) | |
| # $1 = expr, $2 = type, $3 = path | |
| local expr="$1" type="$2" file="$3" | |
| if [ "$type" = "json" ]; then | |
| jq -c "$expr" "$file" 2>/dev/null || true | |
| else | |
| yq -o=json -c "$expr" "$file" 2>/dev/null || true | |
| fi | |
| } | |
| # --------------------------- | |
| # Prepare template | |
| # --------------------------- | |
| cp .templates/.README.md README2.md | |
| ADDONSLINE="$(sed -n '/%%ADDONS_LIST%%/=' README2.md)" | |
| # Keep the placeholder line so INSERT index stays stable | |
| # sed -i '/%%ADDONS_LIST%%/d' README2.md | |
| # --------------------------- | |
| # Sort folders by addon name (supports config.json & config.yaml/.yml) | |
| # --------------------------- | |
| for f in $( find -- * -maxdepth 0 -type d | sort -r ); do | |
| IFS='|' read -r CONFIG TYPE <<<"$(get_config "$f")" | |
| if [ -n "$CONFIG" ]; then | |
| NAME="$(get_raw '.name' "$TYPE" "$CONFIG")" | |
| if [ -n "${NAME:-}" ] && [ "$f" != "$NAME" ]; then | |
| echo "$f" > "$f/oldname" | |
| mv "$f" "$NAME" | |
| fi | |
| fi | |
| done | |
| # --------------------------- | |
| # Populate template | |
| # --------------------------- | |
| find -- * -maxdepth 0 -type d | sort -r | while read -r f; do | |
| IFS='|' read -r CONFIG TYPE <<<"$(get_config "$f")" | |
| if [ -n "$CONFIG" ]; then | |
| echo "Project $f" | |
| # Get variables | |
| if [ -f "$f/oldname" ]; then FOLDERNAME="$(cat "$f/oldname")"; else FOLDERNAME="$f"; fi | |
| NAME="$(get_raw '.name' "$TYPE" "$CONFIG")" | |
| DESCRIPTION="$(get_raw '.description' "$TYPE" "$CONFIG")" | |
| # Icon | |
| PANEL_ICON_RAW="$(get_raw '.panel_icon' "$TYPE" "$CONFIG")" | |
| if [ -n "$PANEL_ICON_RAW" ] && [ "$PANEL_ICON_RAW" != "null" ]; then | |
| ICON="${PANEL_ICON_RAW#*:}" | |
| ICON="" | |
| else | |
| ICON="" | |
| fi | |
| # Derived / checks | |
| SCHEMA_JSON="$(get_jsonc '.schema' "$TYPE" "$CONFIG")" | |
| SERVICES_LIST="$(get_raw '.services[]' "$TYPE" "$CONFIG")" | |
| ARCH_LIST="$(get_raw '.arch[]' "$TYPE" "$CONFIG")" | |
| FULL_ACCESS="$(get_raw '.full_access' "$TYPE" "$CONFIG")" | |
| INGRESS="$(get_raw '.ingress' "$TYPE" "$CONFIG")" | |
| # Write infos | |
| echo "Writing infos" | |
| sed -i "$ADDONSLINE"'{G;}' README2.md | |
| if [[ "$SCHEMA_JSON" == *"localdisks"* ]]; then sed -i "$ADDONSLINE"'a ![localdisks][localdisks-badge]' README2.md; fi | |
| if [[ "$SCHEMA_JSON" == *"networkdisks"* ]]; then sed -i "$ADDONSLINE"'a ![smb][smb-badge]' README2.md; fi | |
| if [[ "$FULL_ACCESS" == "true" ]]; then sed -i "$ADDONSLINE"'a ![full_access][full_access-badge]' README2.md; fi | |
| if [[ "$SERVICES_LIST" == *"mqtt"* ]]; then sed -i "$ADDONSLINE"'a ![mqtt][mqtt-badge]' README2.md; fi | |
| if [[ "$SERVICES_LIST" == *"mysql"* ]]; then sed -i "$ADDONSLINE"'a ![MariaDB][mariadb-badge]' README2.md; fi | |
| if [[ "$INGRESS" == "true" ]]; then sed -i "$ADDONSLINE"'a ![ingress][ingress-badge]' README2.md; fi | |
| if [[ "$ARCH_LIST" == *"amd64"* ]]; then | |
| sed -i "$ADDONSLINE"'a ![amd64][amd64-badge]' README2.md | |
| else | |
| sed -i "$ADDONSLINE"'a ![amd64no][amd64no-badge]' README2.md | |
| fi || true | |
| if [[ "$ARCH_LIST" == *"aarch64"* ]]; then | |
| sed -i "$ADDONSLINE"'a ![aarch64][aarch64-badge]' README2.md | |
| else | |
| sed -i "$ADDONSLINE"'a ![aarch64no][aarch64no-badge]' README2.md | |
| fi || true | |
| if [[ -f "$f/updater.json" ]]; then | |
| sed -i "$ADDONSLINE"'a ' README2.md | |
| fi | |
| # Version badge: JSON vs YAML endpoint | |
| if [ "$TYPE" = "json" ]; then | |
| sed -i "$ADDONSLINE"'a   ' README2.md || true | |
| else | |
| sed -i "$ADDONSLINE"'a   ' README2.md || true | |
| fi | |
| sed -i "$ADDONSLINE"'a ✓ '"$ICON"' ['"$NAME"']('"$FOLDERNAME"'/) : '"$DESCRIPTION\\n" README2.md | |
| fi | |
| done | |
| # --------------------------- | |
| # Restore folders name | |
| # --------------------------- | |
| echo "Restore structure..." | |
| find -- * -maxdepth 0 -type d | sort -r | while read -r f; do | |
| if [ -f "$f/oldname" ]; then | |
| NAME="$(cat "$f/oldname")" | |
| rm "$f/oldname" | |
| mv "$f" "$NAME" | |
| fi | |
| done | |
| echo "... done" | |
| # --------------------------- | |
| # Global stats | |
| # --------------------------- | |
| echo "Global stats..." | |
| # shellcheck disable=SC2002 | |
| STATS_DOWNLOADS="$(awk 'NR==2{print $1}' Stats)" | |
| sed -i "s|%%STATS_DOWNLOADS%%|$STATS_DOWNLOADS|g" README2.md && \ | |
| # Count addons having either config.json or config.yaml/.yml (unique folders) | |
| sed -i "s|%%STATS_ADDONS%%|$(find . -type f \( -name 'config.json' -o -name 'config.yaml' -o -name 'config.yml' \) -printf '%h\n' | sort -u | wc -l)|g" README2.md && \ | |
| STATS_ONE="$(awk 'NR==3{print $(NF)}' Stats)" && \ | |
| STATS_TWO="$(awk 'NR==4{print $(NF)}' Stats)" && \ | |
| STATS_THREE="$(awk 'NR==5{print $(NF)}' Stats)" | |
| echo "Best addon is $STATS_ONE" | |
| sed -i "s|%%STATS_ONE%%|${STATS_ONE^}|g" README2.md | |
| sed -i "s|%%STATS_TWO%%|${STATS_TWO^}|g" README2.md | |
| sed -i "s|%%STATS_THREE%%|${STATS_THREE^}|g" README2.md | |
| echo "... done" | |
| # --------------------------- | |
| # Breakdown per arch | |
| # --------------------------- | |
| echo "Breakdown per arch..." | |
| STATS_AMD64="$(awk '{SUM+=$3}END{print SUM}' Stats2)" | |
| STATS_AARCH64="$(awk '{SUM+=$4}END{print SUM}' Stats2)" | |
| STATS_DOWNLOADS="$(( STATS_AMD64 + STATS_AARCH64 ))" | |
| STATS_AMD64="$(awk -v t2="$STATS_AMD64" -v t4="$STATS_DOWNLOADS" 'BEGIN{printf "%.0f", (t4==0?0:t2/t4*100)}')" | |
| STATS_AARCH64="$(awk -v t3="$STATS_AARCH64" -v t4="$STATS_DOWNLOADS" 'BEGIN{printf "%.0f", (t4==0?0:t3/t4*100)}')" | |
| sed -i "s|%%STATS_AMD64%%|amd64: ${STATS_AMD64}%|g" README2.md | |
| sed -i "s|%%STATS_AARCH64%%|aarch64: ${STATS_AARCH64}%|g" README2.md | |
| echo "... done" | |
| for var in "$STATS_ONE" "$STATS_TWO" "$STATS_THREE"; do | |
| i=0 | |
| j=0 | |
| k=0 | |
| # shellcheck disable=SC2013 | |
| for i in $(sed -n "/$var/p" Stats); do | |
| k="$((k+1))" | |
| if [ "$k" -eq 3 ]; then break; fi | |
| if [ "$i" -eq "$i" ] 2>/dev/null && [ "$i" -gt "$j" ]; then j="$i"; fi | |
| done | |
| sed -i "s|${var^}|${var^} (${j}x)|g" README2.md | |
| echo "$STATS_ONE has $j downloads" | |
| done | |
| echo "... done" | |
| # --------------------------- | |
| # Replace template if change | |
| # --------------------------- | |
| echo "Replace template..." | |
| mv README2.md README.md | |
| echo "... done" | |
| - name: Commit if needed | |
| uses: EndBug/add-and-commit@v9 | |
| with: | |
| message: "GitHub bot : README updated" | |
| default_author: github_actions |