Skip to content

Commit 33a18e4

Browse files
authored
Auto Release Part II: Plugins (#1011)
* Auto Release Part II: Plugins * improve
1 parent 3a0ac40 commit 33a18e4

File tree

1 file changed

+135
-2
lines changed

1 file changed

+135
-2
lines changed

.github/workflows/main.yml

Lines changed: 135 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ jobs:
9595
id: get_version
9696
run: |
9797
sudo apt install xmlstarlet -qq
98+
# Only release when <Version> is explicitly set (dev builds keep <VersionPrefix> and should not release).
9899
VERSION=$(xmlstarlet sel -N i=http://schemas.microsoft.com/developer/msbuild/2003 -t -v "//i:Version/text()" src/Directory.Build.props 2>/dev/null || echo "")
99100
[ -z "$VERSION" ] && VERSION=$(find plugins -name Directory.Build.props | xargs xmlstarlet sel -N i=http://schemas.microsoft.com/developer/msbuild/2003 -t -v "//i:Version/text()" 2>/dev/null || echo "")
100101
[ -n "$VERSION" ] && echo "version=v$VERSION" >> $GITHUB_OUTPUT || echo "version=" >> $GITHUB_OUTPUT
@@ -190,6 +191,96 @@ jobs:
190191
191192
cd "./publish/$platform" && zip -r "../../neo-cli-$platform.zip" . && cd ../..
192193
done
194+
195+
- name: Build and package plugins (zip per plugin)
196+
if: steps.check_tag.outputs.statusCode == '404'
197+
run: |
198+
set -euo pipefail
199+
200+
# Use neo-cli portable publish output as the baseline set of assemblies
201+
if [ ! -d "./publish/portable" ]; then
202+
echo "Error: ./publish/portable not found. neo-cli portable must be published first."
203+
exit 1
204+
fi
205+
206+
mkdir -p "./plugin-publish" "./plugin-zip"
207+
208+
# Collect baseline DLL filenames shipped with neo-cli portable
209+
mapfile -t cli_dlls < <(find "./publish/portable" -maxdepth 1 -type f -name "*.dll" -printf "%f\n" | sort -u)
210+
declare -A cli_dll_set
211+
for f in "${cli_dlls[@]}"; do cli_dll_set["$f"]=1; done
212+
213+
# Package every plugin project under plugins/*/*.csproj (stage only, zip after all are staged)
214+
for csproj in plugins/*/*.csproj; do
215+
plugin_dir="$(dirname "$csproj")"
216+
plugin_name="$(basename "$plugin_dir")"
217+
# Publish plugin (framework-dependent) to get a clean dependency set
218+
plugin_out="./plugin-publish/$plugin_name"
219+
rm -rf "$plugin_out"
220+
dotnet publish "$csproj" -c Release -o "$plugin_out" --self-contained false
221+
222+
# MPTTrie is only used as a dependency (by StateService). We publish it so that MPTTrie.dll
223+
# exists under plugin-publish/, but we don't stage or zip it as a standalone plugin.
224+
if [ "$plugin_name" == "MPTTrie" ]; then
225+
continue
226+
fi
227+
228+
plugin_json="$plugin_dir/$plugin_name.json"
229+
230+
# Staging layout required by release consumers:
231+
# Plugins/<PluginName>/{PluginName}.dll (+ optional {PluginName}.json) + only required extra dependency dlls
232+
stage_root="./plugin-zip/$plugin_name"
233+
stage_dir="$stage_root/Plugins/$plugin_name"
234+
rm -rf "$stage_root"
235+
mkdir -p "$stage_dir"
236+
237+
# Always include the plugin's own assembly
238+
if [ ! -f "$plugin_out/$plugin_name.dll" ]; then
239+
echo "Error: Missing published plugin dll: $plugin_out/$plugin_name.dll"
240+
exit 1
241+
fi
242+
cp "$plugin_out/$plugin_name.dll" "$stage_dir/"
243+
244+
# Include plugin json if present
245+
if [ -f "$plugin_json" ]; then
246+
cp "$plugin_json" "$stage_dir/"
247+
fi
248+
249+
# Only include extra dependency DLLs for plugins that explicitly reference NuGet packages.
250+
# This keeps "pure" project-reference plugins (e.g. DBFTPlugin) minimal: {Plugin}.dll (+ optional json).
251+
if grep -q "<PackageReference" "$csproj"; then
252+
# Include only dlls that neo-cli portable does NOT already ship
253+
shopt -s nullglob
254+
for dep in "$plugin_out"/*.dll; do
255+
dep_name="$(basename "$dep")"
256+
if [ "$dep_name" == "$plugin_name.dll" ]; then
257+
continue
258+
fi
259+
if [ -z "${cli_dll_set["$dep_name"]+x}" ]; then
260+
cp "$dep" "$stage_dir/"
261+
fi
262+
done
263+
shopt -u nullglob
264+
fi
265+
done
266+
267+
# After all plugins are published, ensure StateService staging includes its MPTTrie dependency.
268+
mpt_trie_dll="./plugin-publish/MPTTrie/MPTTrie.dll"
269+
state_stage="./plugin-zip/StateService/Plugins/StateService"
270+
if [ -f "$mpt_trie_dll" ] && [ -d "$state_stage" ]; then
271+
cp "$mpt_trie_dll" "$state_stage/"
272+
fi
273+
274+
# Finally, create zip per plugin from staged directories (excluding MPTTrie by design)
275+
for csproj in plugins/*/*.csproj; do
276+
plugin_dir="$(dirname "$csproj")"
277+
plugin_name="$(basename "$plugin_dir")"
278+
[ "$plugin_name" == "MPTTrie" ] && continue
279+
stage_root="./plugin-zip/$plugin_name"
280+
if [ -d "$stage_root" ]; then
281+
(cd "$stage_root" && zip -r "../../$plugin_name.zip" "Plugins")
282+
fi
283+
done
193284
- name: Upload CLI packages to release
194285
if: steps.check_tag.outputs.statusCode == '404'
195286
env:
@@ -208,6 +299,14 @@ jobs:
208299
for file in neo-cli-portable.zip neo-cli-linux-x64.zip neo-cli-linux-arm64.zip neo-cli-win-x64.zip neo-cli-osx-x64.zip neo-cli-osx-arm64.zip; do
209300
[ ! -f "$file" ] && missing_files+=("$file")
210301
done
302+
303+
# Verify plugin zip files exist (one per plugins/*/*.csproj, except MPTTrie which is only a dependency)
304+
for csproj in plugins/*/*.csproj; do
305+
plugin_dir="$(dirname "$csproj")"
306+
plugin_name="$(basename "$plugin_dir")"
307+
[ "$plugin_name" == "MPTTrie" ] && continue
308+
[ ! -f "$plugin_name.zip" ] && missing_files+=("$plugin_name.zip")
309+
done
211310
212311
if [ ${#missing_files[@]} -gt 0 ]; then
213312
echo "Error: Missing zip files: ${missing_files[*]}"
@@ -221,15 +320,49 @@ jobs:
221320
failed_files+=("$file")
222321
fi
223322
done
323+
324+
# Upload plugin zip files to release (excluding MPTTrie)
325+
for csproj in plugins/*/*.csproj; do
326+
plugin_dir="$(dirname "$csproj")"
327+
plugin_name="$(basename "$plugin_dir")"
328+
[ "$plugin_name" == "MPTTrie" ] && continue
329+
if ! gh release upload "$RELEASE_TAG" "$plugin_name.zip" --clobber; then
330+
failed_files+=("$plugin_name.zip")
331+
fi
332+
done
224333
225334
if [ ${#failed_files[@]} -gt 0 ]; then
226335
echo "Error: Failed to upload: ${failed_files[*]}"
227336
exit 1
228337
fi
229-
- name: Publish to NuGet
338+
- name: Publish core packages to NuGet
230339
if: steps.check_tag.outputs.statusCode == '404'
231340
run: |
232341
dotnet pack -o out -c Release
233-
dotnet nuget push out/*.nupkg -s https://api.nuget.org/v3/index.json -k ${NUGET_TOKEN}
342+
343+
# Push only non-plugin packages here (plugins handled in a separate step)
344+
for pkg in out/*.nupkg; do
345+
name="$(basename "$pkg")"
346+
case "$name" in
347+
Neo.Plugins.*) continue ;;
348+
esac
349+
dotnet nuget push "$pkg" -s https://api.nuget.org/v3/index.json -k "${NUGET_TOKEN}" --skip-duplicate
350+
done
351+
env:
352+
NUGET_TOKEN: ${{ secrets.NUGET_TOKEN }}
353+
354+
- name: Publish plugin packages to NuGet
355+
if: steps.check_tag.outputs.statusCode == '404'
356+
run: |
357+
# Ensure plugin packages are packed (reuse existing 'out' folder to avoid rebuilding everything)
358+
for csproj in plugins/*/*.csproj; do
359+
dotnet pack "$csproj" -c Release -o out
360+
done
361+
362+
# Push all Neo.Plugins.* packages to NuGet.org
363+
for pkg in out/Neo.Plugins.*.nupkg; do
364+
[ -f "$pkg" ] || continue
365+
dotnet nuget push "$pkg" -s https://api.nuget.org/v3/index.json -k "${NUGET_TOKEN}" --skip-duplicate
366+
done
234367
env:
235368
NUGET_TOKEN: ${{ secrets.NUGET_TOKEN }}

0 commit comments

Comments
 (0)