From 8d6e6296d69e39fab377bdc33281ade9202e05aa Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:44 -0500 Subject: [PATCH 01/26] chore: update LICENSE from MokoStandards -- 2.52.0 From ec6165618f4d0276258a035fb953dafaa6f9aca8 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:45 -0500 Subject: [PATCH 02/26] chore: update update.xml from MokoStandards -- 2.52.0 From b015ae6591a0acdec7bae49172705d64bacc9f87 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:45 -0500 Subject: [PATCH 03/26] chore: update phpstan.neon from MokoStandards -- 2.52.0 From a15469f7afc5745e1031bffaf83ec2c98102ab27 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:46 -0500 Subject: [PATCH 04/26] chore: update Makefile from MokoStandards -- 2.52.0 From 396cbf64b56409ce37d0c275e703b6c541123065 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:47 -0500 Subject: [PATCH 05/26] chore: update .gitignore from MokoStandards -- 2.52.0 From c6860ca535dab3d56487946d0e29de34ebd32e06 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:47 -0500 Subject: [PATCH 06/26] chore: update composer.json from MokoStandards -- 2.52.0 From 42a3b355159fa99f5c416d28227d49dff198bb3a Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:48 -0500 Subject: [PATCH 07/26] chore: update .moko-standards from MokoStandards -- 2.52.0 From 3f382179d5813b8bff93954b2d75b725e5998858 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:49 -0500 Subject: [PATCH 08/26] chore: update .github/copilot.yml from MokoStandards -- 2.52.0 From 0c18815d022937679a7bf301333a3115edcde673 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:50 -0500 Subject: [PATCH 09/26] chore: update .github/copilot-instructions.md from MokoStandards -- 2.52.0 From c119bf6b5739eee58abbc313d72a571ccba5b360 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:51 -0500 Subject: [PATCH 10/26] chore: update .github/CLAUDE.md from MokoStandards -- 2.52.0 From bab93d8b69dcccff7ff19fcd63efde506fdc42a6 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:52 -0500 Subject: [PATCH 11/26] chore: update .github/workflows/codeql-analysis.yml from MokoStandards -- 2.52.0 From 895546b1c2a044ef121f5bcc7a006e3e413e9808 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:52 -0500 Subject: [PATCH 12/26] chore: update .github/workflows/standards-compliance.yml from MokoStandards -- 2.52.0 From 1c4533fe516e359ca2f7550b1fad29453bc8387b Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:53 -0500 Subject: [PATCH 13/26] chore: update .github/workflows/enterprise-firewall-setup.yml from MokoStandards -- 2.52.0 From 927db052492af209e766331942b4666a3e502940 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:54 -0500 Subject: [PATCH 14/26] chore: update .github/workflows/deploy-dev.yml from MokoStandards --- .github/workflows/deploy-dev.yml | 111 ++++++++++++++++++++++--------- 1 file changed, 79 insertions(+), 32 deletions(-) diff --git a/.github/workflows/deploy-dev.yml b/.github/workflows/deploy-dev.yml index af69789..dc271dc 100644 --- a/.github/workflows/deploy-dev.yml +++ b/.github/workflows/deploy-dev.yml @@ -22,7 +22,7 @@ # INGROUP: MokoStandards.Deploy # REPO: https://github.com/mokoconsulting-tech/MokoStandards # PATH: /templates/workflows/shared/deploy-dev.yml -# VERSION: 04.00.25 +# VERSION: 04.00.27 # BRIEF: SFTP deployment workflow for development server — synced to all governed repos # NOTE: Synced via bulk-repo-sync to .github/workflows/deploy-dev.yml in all governed repos. # Port is resolved in order: DEV_FTP_PORT variable → :port suffix in DEV_FTP_HOST → 22. @@ -35,14 +35,11 @@ name: Deploy to Dev Server (SFTP) # # Required org-level variables: DEV_FTP_HOST, DEV_FTP_PATH, DEV_FTP_USERNAME # Optional org-level variable: DEV_FTP_PORT (auto-detected from host or defaults to 22) -# Optional org/repo variable: DEV_FTP_PATH_SUFFIX -# Optional org/repo variable: CUSTOM_FOLDER — when set, appended to the remote path after -# DEV_FTP_PATH_SUFFIX; used automatically for Dolibarr modules -# Optional org/repo variable: FTP_IGNORE — comma-delimited list of regex patterns, each enclosed in -# double quotes, for files/paths to exclude from upload, e.g.: -# "\.git*", "\.DS_Store", "configuration\.php", "\.ps1" -# Patterns are tested against the forward-slash relative path of each -# file (e.g. "subdir/file.txt"). The repository .gitignore is also +# Optional org/repo variable: CUSTOM_NAME — when set, appended to DEV_FTP_PATH to form the +# full remote destination: DEV_FTP_PATH/CUSTOM_NAME +# Ignore rules: Place a .ftp_ignore file in the repository root. Each non-empty, +# non-comment line is a regex pattern tested against the relative path +# of each file (e.g. "subdir/file.txt"). The .gitignore is also # respected automatically. # Required org-level secret: DEV_FTP_KEY (preferred) or DEV_FTP_PASSWORD # @@ -163,15 +160,47 @@ jobs: if: steps.source.outputs.skip == 'false' env: SOURCE_DIR: ${{ steps.source.outputs.dir }} - FTP_IGNORE: ${{ vars.FTP_IGNORE }} run: | - # ── Parse FTP_IGNORE ───────────────────────────────────────────────── + # ── Convert a gitignore-style glob line to an ERE pattern ────────────── + ftp_ignore_to_regex() { + local line="$1" + local anchored=false + # Strip inline comments and whitespace + line=$(printf '%s' "$line" | sed 's/[[:space:]]*#.*$//' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + [ -z "$line" ] && return + # Skip negation patterns (not supported) + [[ "$line" == !* ]] && return + # Trailing slash = directory marker; strip it + line="${line%/}" + # Leading slash = anchored to root; strip it + if [[ "$line" == /* ]]; then + anchored=true + line="${line#/}" + fi + # Escape ERE special chars, then restore glob semantics + local regex + regex=$(printf '%s' "$line" \ + | sed 's/[.+^${}()|[\\]/\\&/g' \ + | sed 's/\\\*\\\*/\x01/g' \ + | sed 's/\\\*/[^\/]*/g' \ + | sed 's/\x01/.*/g' \ + | sed 's/\\\?/[^\/]/g') + if $anchored; then + printf '^%s(/|$)' "$regex" + else + printf '(^|/)%s(/|$)' "$regex" + fi + } + + # ── Read .ftp_ignore (gitignore-style globs) ───────────────────────── IGNORE_PATTERNS=() - if [ -n "$FTP_IGNORE" ]; then - while IFS= read -r -d ',' token; do - pattern=$(printf '%s' "$token" | sed 's/^[[:space:]]*"//;s/"[[:space:]]*$//') - [ -n "$pattern" ] && IGNORE_PATTERNS+=("$pattern") - done <<< "${FTP_IGNORE}," + IGNORE_SOURCES=() + if [ -f ".ftp_ignore" ]; then + while IFS= read -r line; do + [[ "$line" =~ ^[[:space:]]*$ || "$line" =~ ^[[:space:]]*# ]] && continue + regex=$(ftp_ignore_to_regex "$line") + [ -n "$regex" ] && IGNORE_PATTERNS+=("$regex") && IGNORE_SOURCES+=("$line") + done < ".ftp_ignore" fi # ── Walk src/ and classify every file ──────────────────────────────── @@ -180,9 +209,9 @@ jobs: while IFS= read -r -d '' file; do rel="${file#${SOURCE_DIR}/}" SKIP=false - for pat in "${IGNORE_PATTERNS[@]}"; do - if echo "$rel" | grep -qE "$pat" 2>/dev/null; then - IGNORED_FILES+=("$rel | FTP_IGNORE \`$pat\`") + for i in "${!IGNORE_PATTERNS[@]}"; do + if echo "$rel" | grep -qE "${IGNORE_PATTERNS[$i]}" 2>/dev/null; then + IGNORED_FILES+=("$rel | .ftp_ignore \`${IGNORE_SOURCES[$i]}\`") SKIP=true; break fi done @@ -262,13 +291,10 @@ jobs: if: steps.source.outputs.skip == 'false' id: remote env: - DEV_FTP_PATH: ${{ vars.DEV_FTP_PATH }} - DEV_FTP_PATH_SUFFIX: ${{ vars.DEV_FTP_PATH_SUFFIX }} - CUSTOM_FOLDER: ${{ vars.CUSTOM_FOLDER }} + DEV_FTP_PATH: ${{ vars.DEV_FTP_PATH }} + CUSTOM_NAME: ${{ vars.CUSTOM_NAME }} run: | BASE="$DEV_FTP_PATH" - SUFFIX="$DEV_FTP_PATH_SUFFIX" - CUSTOM="$CUSTOM_FOLDER" if [ -z "$BASE" ]; then echo "❌ DEV_FTP_PATH is not set." @@ -277,21 +303,42 @@ jobs: exit 1 fi - # Always append suffix when set — path is BASE/SUFFIX - if [ -n "$SUFFIX" ]; then - REMOTE="${BASE%/}/${SUFFIX#/}" + # Path format: DEV_FTP_PATH/CUSTOM_NAME (CUSTOM_NAME is optional) + if [ -n "$CUSTOM_NAME" ]; then + REMOTE="${BASE%/}/${CUSTOM_NAME#/}" else REMOTE="$BASE" fi - # Append CUSTOM_FOLDER when set — makes Dolibarr module paths automatic - if [ -n "$CUSTOM" ]; then - REMOTE="${REMOTE%/}/${CUSTOM#/}" - echo "ℹ️ CUSTOM_FOLDER appended: ${CUSTOM}" + # ── Platform-specific path safety guards ────────────────────────────── + PLATFORM="" + if [ -f ".moko-standards" ]; then + PLATFORM=$(grep -E '^platform:' .moko-standards | sed 's/.*:[[:space:]]*//' | tr -d '"') fi + if [ "$PLATFORM" = "crm-module" ]; then + # Dolibarr modules must deploy under htdocs/custom/ — guard against + # accidentally overwriting server root or unrelated directories. + if [[ "$REMOTE" != *custom* ]]; then + echo "❌ Safety check failed: Dolibarr (crm-module) remote path must contain 'custom'." + echo " Current path: ${REMOTE}" + echo " Set CUSTOM_NAME to the module's htdocs/custom/ subdirectory." + exit 1 + fi + fi + + if [ "$PLATFORM" = "waas-component" ]; then + # Joomla extensions may only deploy to the server's tmp/ directory. + if [[ "$REMOTE" != *tmp* ]]; then + echo "❌ Safety check failed: Joomla (waas-component) remote path must contain 'tmp'." + echo " Current path: ${REMOTE}" + echo " Set CUSTOM_NAME to a path under the server tmp/ directory." + exit 1 + fi + fi + + echo "ℹ️ Remote path: ${REMOTE}" echo "path=${REMOTE}" >> "$GITHUB_OUTPUT" - echo "Remote path: ${REMOTE}" - name: Detect SFTP authentication method if: steps.source.outputs.skip == 'false' -- 2.52.0 From 0cdc896fcd64c4342f7ce9c5083ba4712fc6a0dc Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:54 -0500 Subject: [PATCH 15/26] chore: update .github/ISSUE_TEMPLATE/config.yml from MokoStandards -- 2.52.0 From b08d0e70f77d9b812adb87d5e79c7601745e4c53 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:55 -0500 Subject: [PATCH 16/26] chore: update .github/ISSUE_TEMPLATE/adr.md from MokoStandards -- 2.52.0 From 3ab60186869e670d1695b4a05891fccd1bbe177b Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:56 -0500 Subject: [PATCH 17/26] chore: update .github/ISSUE_TEMPLATE/bug_report.md from MokoStandards -- 2.52.0 From a879c0eb21e93047b991ee4a05a399a6146a691a Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:56 -0500 Subject: [PATCH 18/26] chore: update .github/ISSUE_TEMPLATE/documentation.md from MokoStandards -- 2.52.0 From c6b08d7e3e6a7960eff722808fbd19cc70dd0e93 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:57 -0500 Subject: [PATCH 19/26] chore: update .github/ISSUE_TEMPLATE/enterprise_support.md from MokoStandards -- 2.52.0 From 9b02a6b7b5d1f516bd72c7b2f59d380e221ff4e3 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:58 -0500 Subject: [PATCH 20/26] chore: update .github/ISSUE_TEMPLATE/feature_request.md from MokoStandards -- 2.52.0 From 7c7609bbbf8509fb07534f6e7aa66414557c2c2c Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:59 -0500 Subject: [PATCH 21/26] chore: update .github/ISSUE_TEMPLATE/firewall-request.md from MokoStandards -- 2.52.0 From f7e0626a1e7b556d292cc3811fa0c74c0cdc9845 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:05:59 -0500 Subject: [PATCH 22/26] chore: update .github/ISSUE_TEMPLATE/question.md from MokoStandards -- 2.52.0 From 2d28dc22fc037793b7c91759b686f3c7296b698c Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:06:00 -0500 Subject: [PATCH 23/26] chore: update .github/ISSUE_TEMPLATE/request-license.md from MokoStandards -- 2.52.0 From c3c37438323704393033101776dd35568eb5f71a Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:06:01 -0500 Subject: [PATCH 24/26] chore: update .github/ISSUE_TEMPLATE/rfc.md from MokoStandards -- 2.52.0 From 01e253cc8865243c0507eca09dca0c91ec7c985c Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:06:01 -0500 Subject: [PATCH 25/26] chore: update .github/ISSUE_TEMPLATE/security.md from MokoStandards -- 2.52.0 From 1defc7d29e12c9c4fc775a5665c414c22dc01bbc Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:06:02 -0500 Subject: [PATCH 26/26] chore: update .github/ISSUE_TEMPLATE/joomla_issue.md from MokoStandards -- 2.52.0