-
-
Notifications
You must be signed in to change notification settings - Fork 0
228 lines (199 loc) · 8.83 KB
/
Copy pathbuild_push.yml
File metadata and controls
228 lines (199 loc) · 8.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
name: Build + publish plugins to repo branch
# Aniyomi-style distribution:
# main branch = C# plugin source projects
# repo branch = built DLLs under dll/ + index.json + index.min.json
# Operators fetch DLLs from raw.githubusercontent.com/schulydev/SchulyPlugins/repo/dll/<name>-v<version>.dll
# and the index from .../repo/index.min.json.
#
# Adding a new plugin = creating a new Schuly.Plugin.<Name>/ folder with a csproj. No workflow change needed.
on:
push:
branches: [main]
paths:
- 'src/Schuly.Plugin.*/**'
- '.github/workflows/build_push.yml'
workflow_dispatch:
# Cancel an in-flight run if a newer push to the same ref starts a new one
# (e.g. force-push from a Co-Authored-By scrub). Keeps only the newest run.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
jobs:
discover:
name: Discover plugin projects
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.find.outputs.matrix }}
steps:
- uses: actions/checkout@v5
- id: find
run: |
plugins=$(find src -maxdepth 2 -type f -name 'Schuly.Plugin.*.csproj' | sort)
if [ -z "$plugins" ]; then
echo "No plugin csprojs found"
echo 'matrix={"include":[]}' >> $GITHUB_OUTPUT
exit 0
fi
matrix=$(echo "$plugins" | jq -R '.' | jq -sc '{include: map({csproj: .})}')
echo "matrix=$matrix" >> $GITHUB_OUTPUT
echo "Plugins to build:"
echo "$plugins"
build:
name: Build plugin
needs: discover
if: ${{ fromJson(needs.discover.outputs.matrix).include[0] != null }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.discover.outputs.matrix) }}
steps:
- uses: actions/checkout@v5
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Read plugin metadata
id: meta
run: |
csproj='${{ matrix.csproj }}'
name=$(dotnet msbuild "$csproj" -getProperty:AssemblyName -nologo | tail -n1 | tr -d ' \r\n')
version=$(dotnet msbuild "$csproj" -getProperty:Version -nologo | tail -n1 | tr -d ' \r\n')
desc=$(dotnet msbuild "$csproj" -getProperty:Description -nologo | tail -n1 | tr -d ' \r\n')
authors=$(dotnet msbuild "$csproj" -getProperty:Authors -nologo | tail -n1 | tr -d ' \r\n')
pkg=$(echo "$name" | tr '[:upper:]' '[:lower:]')
echo "name=$name" >> $GITHUB_OUTPUT
echo "version=$version" >> $GITHUB_OUTPUT
echo "desc=$desc" >> $GITHUB_OUTPUT
echo "authors=$authors" >> $GITHUB_OUTPUT
echo "pkg=$pkg" >> $GITHUB_OUTPUT
echo "Plugin: $name v$version"
- name: Build
run: dotnet publish '${{ matrix.csproj }}' -c Release -o ./out
- name: Stage DLL + dependency zip + per-plugin metadata
run: |
mkdir -p staging/dll
name='${{ steps.meta.outputs.name }}'
version='${{ steps.meta.outputs.version }}'
dll_name="${name}-v${version}.dll"
deps_name="${name}-v${version}-deps.zip"
# The plugin's own DLL ships standalone — operators can pin/swap it
# independently from its bundled dependencies.
cp "./out/${name}.dll" "staging/dll/${dll_name}"
# Drop host-provided / framework assemblies from the deps payload.
# The backend already has these via its own NuGet refs or the .NET
# shared framework; shipping duplicates just wastes disk.
mkdir -p deps-staging
shopt -s extglob nullglob
for f in ./out/*.dll; do
base=$(basename "$f")
case "$base" in
# The plugin's own DLL ships separately (above).
"${name}.dll") continue ;;
# Host-provided assemblies.
Microsoft.AspNetCore.*|Microsoft.Extensions.*) continue ;;
Microsoft.EntityFrameworkCore.*|Npgsql.*) continue ;;
Mediator.*) continue ;;
Schuly.Plugin.Abstractions.dll|Schuly.Domain.dll|Schuly.Infrastructure.dll) continue ;;
*) cp "$f" "deps-staging/$base" ;;
esac
done
# Always produce the zip so the index schema is uniform. If a plugin
# has zero third-party deps (everything is host-shared) the zip just
# carries a marker file — operators see no extra DLLs but the artifact
# still exists.
if [ -z "$(ls -A deps-staging)" ]; then
echo "Plugin has no third-party deps." > deps-staging/.empty
fi
(cd deps-staging && zip -q "../staging/dll/${deps_name}" -r .)
jq -n \
--arg name "$name" \
--arg pkg '${{ steps.meta.outputs.pkg }}' \
--arg dll "$dll_name" \
--arg deps "$deps_name" \
--arg version "$version" \
--arg description '${{ steps.meta.outputs.desc }}' \
--arg authors '${{ steps.meta.outputs.authors }}' \
'{name: $name, pkg: $pkg, dll: $dll, deps: $deps, version: $version, description: $description, authors: $authors}' \
> 'staging/${{ steps.meta.outputs.pkg }}.json'
- uses: actions/upload-artifact@v4
with:
name: plugin-${{ steps.meta.outputs.pkg }}
path: staging
retention-days: 1
publish:
name: Publish to repo branch
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download plugin artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
pattern: plugin-*
merge-multiple: true
- name: Build index.json + index.min.json
run: |
mkdir -p out
# Merge per-plugin metadata into a single index array
jq -s '. | sort_by(.name)' artifacts/*.json > out/index.json
jq -c '.' out/index.json > out/index.min.json
mkdir -p out/dll
cp artifacts/dll/*.dll out/dll/
# Also the per-plugin dependency zips alongside the DLLs.
cp artifacts/dll/*-deps.zip out/dll/ 2>/dev/null || true
ls -R out
- name: Checkout (or init) repo branch
run: |
git clone --branch repo https://x-access-token:${{ secrets.MAIN_PUSH_TOKEN }}@github.com/${{ github.repository }}.git repo-branch 2>/dev/null || {
mkdir repo-branch && cd repo-branch
git init -q -b repo
git remote add origin https://x-access-token:${{ secrets.MAIN_PUSH_TOKEN }}@github.com/${{ github.repository }}.git
echo "# Schuly plugins (repo branch)" > README.md
echo "DLLs and index are auto-generated. Source lives on main." >> README.md
git add README.md
git -c user.name=PianoNic -c user.email=79938743+PianoNic@users.noreply.github.com commit -q -m "Init repo branch"
git push origin repo
cd ..
}
- name: Sync DLLs + index + README into repo branch
run: |
cd repo-branch
rm -rf dll index.json index.min.json
cp -r ../out/dll .
cp ../out/index.json ../out/index.min.json .
# Install instructions live on the repo branch so operators landing
# via raw.githubusercontent get the README beside the artifacts.
cat > README.md <<'EOF'
# Schuly plugins (auto-generated)
DLLs + index built from `main`. Each plugin ships as:
- `dll/<name>-v<version>.dll` — the plugin assembly itself
- `dll/<name>-v<version>-deps.zip` — its third-party dependencies (zipped)
- `index.min.json` — machine-readable catalog
## Install
```sh
BASE=https://raw.githubusercontent.com/schulydev/SchulyPlugins/repo
NAME=Schuly.Plugin.Schulware
VERSION=2.2.2
# 1. Drop the plugin DLL into the backend's plugins/ folder
curl -L "$BASE/dll/$NAME-v$VERSION.dll" -o /app/plugins/$NAME.dll
# 2. Extract its dependencies into the same folder
curl -L "$BASE/dll/$NAME-v$VERSION-deps.zip" -o /tmp/deps.zip
unzip -o /tmp/deps.zip -d /app/plugins/
# 3. Drop the plugin's YAML config into plugins-config/
```
Framework + host-shared assemblies are not in the deps zip; the
backend already provides them. Only the plugin's true third-party
NuGet dependencies (Kiota, etc.) are bundled.
EOF
git config user.name "PianoNic"
git config user.email "79938743+PianoNic@users.noreply.github.com"
git add -A
if [ -z "$(git status --porcelain)" ]; then
echo "No changes to plugin distribution."
exit 0
fi
git commit -m "Publish plugins from main @ ${{ github.sha }}"
git push origin repo