3939 with :
4040 dotnet-version : " 9.0.x"
4141
42- # Note:
43- # - You can cross-publish for other OSes on ubuntu-latest by changing RID (e.g., win-x64, osx-arm64).
44- # - macOS binaries produced here are unsigned; signing/notarization must be performed on macOS.
4542 - name : Publish single-file
4643 id : publish
4744 shell : bash
5047 run : |
5148 set -euo pipefail
5249 PROJ="Server.Stdio/Server.Stdio.csproj"
53- echo "Publishing $PROJ for RID=$RID"
5450
5551 dotnet publish "$PROJ" -c Release -r "$RID" \
5652 -p:PublishSingleFile=true \
@@ -61,34 +57,46 @@ jobs:
6157 TF=$(dotnet msbuild "$PROJ" -getproperty:TargetFramework -nologo -v:quiet)
6258 PUB_DIR="$(dirname "$PROJ")/bin/Release/${TF}/${RID}/publish"
6359 echo "publish_dir=$PUB_DIR" >> "$GITHUB_OUTPUT"
64- echo "Publish dir: $PUB_DIR"
6560
61+ # Find the executable deterministically and resolve to an absolute path
6662 if [[ "$RID" == win* ]]; then
67- EXE =$(find "$PUB_DIR" -maxdepth 1 -type f -name "*.exe" | head -n1 || true)
63+ EXE_PATH =$(find "$PUB_DIR" -maxdepth 1 -type f -name "*.exe" -print -quit || true)
6864 else
69- EXE=$(find "$PUB_DIR" -maxdepth 1 -type f -perm -u+x -printf '%f\n' -exec test -f "$PUB_DIR/{}" \; -print | head -n1 || true)
70- # Fallback in case -printf isn't supported
71- if [ -z "$EXE" ]; then EXE=$(find "$PUB_DIR" -maxdepth 1 -type f -perm -u+x | head -n1 || true); fi
65+ # Prefer a file named Server.Stdio if present; otherwise any user-executable file
66+ EXE_PATH=$(find "$PUB_DIR" -maxdepth 1 -type f -name "Server.Stdio" -perm -u+x -print -quit || true)
67+ if [ -z "$EXE_PATH" ]; then
68+ EXE_PATH=$(find "$PUB_DIR" -maxdepth 1 -type f -perm -u+x -print -quit || true)
69+ fi
7270 fi
7371
74- if [ -z "$EXE " ]; then
72+ if [ -z "$EXE_PATH " ]; then
7573 echo "No executable found in $PUB_DIR" >&2
7674 ls -la "$PUB_DIR" || true
7775 exit 1
7876 fi
79- # Normalize to absolute path
80- if [[ ! "$EXE" = /* ]]; then EXE="$PUB_DIR/$EXE"; fi
81- echo "exe=$EXE" >> "$GITHUB_OUTPUT"
82- echo "Executable: $EXE"
77+
78+ # Resolve to absolute path to avoid later path concatenation issues
79+ if command -v readlink >/dev/null 2>&1; then
80+ EXE_ABS=$(readlink -f "$EXE_PATH")
81+ else
82+ EXE_ABS=$(python3 - << 'PY'
83+ import os,sys
84+ p=sys.argv[1]
85+ print(os.path.abspath(p))
86+ PY
87+ " $EXE_PATH" )
88+ fi
89+
90+ echo "exe=$EXE_ABS" >> "$GITHUB_OUTPUT"
91+ echo "Executable : $EXE_ABS"
8392
8493 # Detect sidecar native libraries (needed on some RIDs like macOS)
8594 SIDECAR=""
8695 for pattern in "*.so" "*.dylib"; do
87- CAND=$(find "$PUB_DIR" -maxdepth 1 -type f -name "$pattern" | head -n1 || true)
96+ CAND=$(find "$PUB_DIR" -maxdepth 1 -type f -name "$pattern" -print -quit || true)
8897 if [ -n "$CAND" ]; then SIDECAR="$CAND"; break; fi
8998 done
9099 echo "sidecar=$SIDECAR" >> "$GITHUB_OUTPUT"
91- if [ -n "$SIDECAR" ]; then echo "Detected sidecar: $SIDECAR"; else echo "No sidecar native lib detected"; fi
92100
93101 - name : Prepare native asset
94102 id : package
@@ -98,25 +106,20 @@ jobs:
98106 TAG : ${{ github.ref_name }}
99107 run : |
100108 set -euo pipefail
101- EXT=""
102- if [[ "$RID" == win* ]]; then EXT=".exe"; fi
109+ EXT=""; [[ "$RID" == win* ]] && EXT=".exe"
103110 BASENAME="mcp-server-stdio-${TAG}-${RID}${EXT}"
104111 SRC="${{ steps.publish.outputs.exe }}"
105- DEST_DIR="$(mktemp -d)"
106- DEST="$DEST_DIR/$BASENAME"
112+ DEST_DIR="$(mktemp -d)"; DEST="$DEST_DIR/$BASENAME"
107113 cp "$SRC" "$DEST"
108114 chmod +x "$DEST" || true
109115 echo "asset=$DEST" >> "$GITHUB_OUTPUT"
110- echo "Prepared native asset: $DEST"
111116
112- # If sidecar exists, prepare it with a deterministic name
113117 SIDECAR_SRC="${{ steps.publish.outputs.sidecar }}"
114118 if [ -n "$SIDECAR_SRC" ]; then
115119 SNAME="mcp-server-stdio-${TAG}-${RID}-$(basename "$SIDECAR_SRC")"
116120 SC_DEST="$DEST_DIR/$SNAME"
117121 cp "$SIDECAR_SRC" "$SC_DEST"
118122 echo "sidecar_asset=$SC_DEST" >> "$GITHUB_OUTPUT"
119- echo "Prepared sidecar asset: $SC_DEST"
120123 else
121124 echo "sidecar_asset=" >> "$GITHUB_OUTPUT"
122125 fi
0 commit comments