2026-07-14 15:58:35 -05:00 | | | #!/bin/sh
|
| | | # Auto-version, compile, and prune EA releases. Fires after every commit on main.
|
| | | # Pattern: sequential build-NNNN git tags + matching archived .ex5 builds,
|
| | | # capped at MAX_KEEP by deleting the oldest ones each time the cap is exceeded.
|
| | |
|
| | | REPO_ROOT="$(git rev-parse --show-toplevel)"
|
| | | cd "$REPO_ROOT" || exit 0
|
| | |
|
| | | BRANCH="$(git rev-parse --abbrev-ref HEAD)"
|
| | | [ "$BRANCH" = "main" ] || exit 0
|
| | |
|
| | | MAX_KEEP=10
|
| | | MQ5_FILE="$REPO_ROOT/profitgtx.mq5"
|
| | | BUILD_DIR="$REPO_ROOT/builds"
|
| | | METAEDITOR="/c/Program Files/MetaTrader 5 Terminal/MetaEditor64.exe"
|
| | |
|
| | | mkdir -p "$BUILD_DIR"
|
| | |
|
| | | # 1. Next sequential build number, derived from existing tags (no state file needed)
|
| | | LAST=$(git tag -l "build-*" | sed 's/^build-//' | sort -n | tail -1)
|
| | | [ -z "$LAST" ] && LAST=0
|
| | | NEXT=$((10#$LAST + 1))
|
| | | TAG=$(printf "build-%04d" "$NEXT")
|
| | |
|
| | | # 2. Tag this commit
|
| | | git tag -a "$TAG" -m "Automated build $TAG" || exit 0
|
| | |
|
| | | # 3. Compile via MetaEditor CLI and archive the .ex5 on success
|
2026-07-14 16:02:16 -05:00 | | | # MetaEditor64.exe hands off to an already-running instance and returns
|
| | | # immediately without waiting for the compile to finish, so poll for the
|
| | | # log file to appear and stop growing before reading it.
|
2026-07-14 15:58:35 -05:00 | | | LOG_FILE="$BUILD_DIR/$TAG.log"
|
2026-07-14 16:02:16 -05:00 | | | rm -f "$LOG_FILE"
|
2026-07-14 15:58:35 -05:00 | | | if [ -f "$MQ5_FILE" ] && [ -x "$METAEDITOR" ]; then
|
| | | "$METAEDITOR" /compile:"$MQ5_FILE" /log:"$LOG_FILE" >/dev/null 2>&1
|
2026-07-14 16:02:16 -05:00 | | |
|
| | | TRIES=0
|
| | | LAST_SIZE=-1
|
| | | while [ "$TRIES" -lt 30 ]; do
|
| | | sleep 1
|
| | | TRIES=$((TRIES + 1))
|
| | | [ -f "$LOG_FILE" ] || continue
|
| | | CUR_SIZE=$(wc -c < "$LOG_FILE" 2>/dev/null || echo 0)
|
| | | [ "$CUR_SIZE" = "$LAST_SIZE" ] && [ "$CUR_SIZE" -gt 0 ] && break
|
| | | LAST_SIZE=$CUR_SIZE
|
| | | done
|
| | |
|
2026-07-14 15:58:35 -05:00 | | | LOG_TEXT=$(iconv -f UTF-16LE -t UTF-8 "$LOG_FILE" 2>/dev/null || cat "$LOG_FILE" 2>/dev/null)
|
| | | if echo "$LOG_TEXT" | grep -qi "0 error"; then
|
| | | EX5_SRC="${MQ5_FILE%.mq5}.ex5"
|
| | | [ -f "$EX5_SRC" ] && cp "$EX5_SRC" "$BUILD_DIR/profitgtx_$TAG.ex5"
|
| | | echo "[post-commit] Built and archived $TAG"
|
| | | else
|
| | | echo "[post-commit] WARNING: compile for $TAG reported errors, see $LOG_FILE"
|
| | | fi
|
| | | fi
|
| | |
|
| | | # 4. Push commit + tag
|
| | | git push origin main "$TAG" >/dev/null 2>&1 || echo "[post-commit] WARNING: push failed, tag/build kept locally"
|
| | |
|
| | | # 5. Prune tags beyond MAX_KEEP (oldest first, local + remote)
|
| | | TAG_NUMS=$(git tag -l "build-*" | sed 's/^build-//' | sort -n)
|
| | | TAG_COUNT=$(printf '%s\n' "$TAG_NUMS" | grep -c .)
|
| | | if [ "$TAG_COUNT" -gt "$MAX_KEEP" ]; then
|
| | | EXCESS=$((TAG_COUNT - MAX_KEEP))
|
| | | printf '%s\n' "$TAG_NUMS" | head -n "$EXCESS" | while read -r n; do
|
| | | OLDTAG="build-$(printf '%04d' "$n")"
|
| | | git tag -d "$OLDTAG" >/dev/null 2>&1
|
| | | git push origin ":refs/tags/$OLDTAG" >/dev/null 2>&1
|
| | | echo "[post-commit] Pruned tag $OLDTAG"
|
| | | done
|
| | | fi
|
| | |
|
| | | # 6. Prune archived .ex5 builds beyond MAX_KEEP (oldest first)
|
| | | BUILD_NUMS=$(ls "$BUILD_DIR" 2>/dev/null | grep -E '^profitgtx_build-[0-9]{4}\.ex5$' | sed -E 's/^profitgtx_build-([0-9]{4})\.ex5$/\1/' | sort -n)
|
| | | BUILD_COUNT=$(printf '%s\n' "$BUILD_NUMS" | grep -c .)
|
| | | if [ "$BUILD_COUNT" -gt "$MAX_KEEP" ]; then
|
| | | BEXCESS=$((BUILD_COUNT - MAX_KEEP))
|
| | | printf '%s\n' "$BUILD_NUMS" | head -n "$BEXCESS" | while read -r n; do
|
| | | rm -f "$BUILD_DIR/profitgtx_build-$n.ex5" "$BUILD_DIR/build-$n.log"
|
| | | echo "[post-commit] Pruned build artifact build-$n"
|
| | | done
|
| | | fi
|
| | |
|
| | | exit 0
|