-
Notifications
You must be signed in to change notification settings - Fork 0
194 lines (174 loc) · 7.35 KB
/
Copy pathexamples-python.yml
File metadata and controls
194 lines (174 loc) · 7.35 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
# Python SDK CI. Builds every Python example plugin with the inlining build
# tool (sdks/python/owncast_plugin_build.py + extism-py), runs each through
# owncast-plugin-test, and smoke-tests owncast-plugin-serve. The test/serve
# binaries are built from host-runtime against the current owncast runtime, so
# this catches runtime regressions and example breakage together. The JS SDK
# has its own matrix in examples-js.yml.
#
# Layout mirrors examples-js.yml: one `toolchain` job assembles everything the
# Python build needs — the source-built host binaries, the extism-py compiler,
# and binaryen (wasm-merge/wasm-opt, which extism-py shells out to) — into a
# single directory, uploads it as an artifact, and enumerates the examples into
# a matrix. Downstream jobs restore that toolchain instead of rebuilding it.
name: Python Examples
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
concurrency:
group: examples-python-${{ github.ref }}
cancel-in-progress: true
env:
EXTISM_PY_VERSION: v0.1.5
BINARYEN_VERSION: version_119
jobs:
toolchain:
runs-on: ubuntu-latest
outputs:
examples: ${{ steps.discover.outputs.examples }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: host-runtime/go.mod
cache-dependency-path: host-runtime/go.sum
# Build owncast-plugin-test/serve from the current owncast runtime
# (services/plugins). GOPRIVATE + @develop matches release.yml.
- name: Build host binaries from source
working-directory: host-runtime
env:
GOPRIVATE: github.com/owncast/owncast
run: |
go get github.com/owncast/owncast@develop
mkdir -p "$GITHUB_WORKSPACE/pytoolchain/bin" "$GITHUB_WORKSPACE/pytoolchain/share"
go build -o "$GITHUB_WORKSPACE/pytoolchain/bin/owncast-plugin-test" ./cmd/owncast-plugin-test
go build -o "$GITHUB_WORKSPACE/pytoolchain/bin/owncast-plugin-serve" ./cmd/owncast-plugin-serve
# extism-py (the Python->wasm compiler). The release tarball carries the
# binary plus a share/ tree (the embedded CPython engine + wasi-sysroot)
# that extism-py loads from $HOME/.local/share/extism-py at compile time;
# we stash that tree in the artifact and restore it to that path later.
- name: Fetch extism-py
run: |
set -e
url="https://github.com/extism/python-pdk/releases/download/${EXTISM_PY_VERSION}/extism-py-x86_64-linux-${EXTISM_PY_VERSION}.tar.gz"
curl -fsSL "$url" -o /tmp/extism-py.tar.gz
tar xzf /tmp/extism-py.tar.gz -C /tmp
cp /tmp/extism-py/bin/extism-py "$GITHUB_WORKSPACE/pytoolchain/bin/"
cp -r /tmp/extism-py/share/extism-py "$GITHUB_WORKSPACE/pytoolchain/share/extism-py"
# binaryen: extism-py shells out to wasm-merge/wasm-opt (which need
# libbinaryen from lib/).
- name: Fetch binaryen
run: |
set -e
url="https://github.com/WebAssembly/binaryen/releases/download/${BINARYEN_VERSION}/binaryen-${BINARYEN_VERSION}-x86_64-linux.tar.gz"
curl -fsSL "$url" -o /tmp/binaryen.tar.gz
tar xzf /tmp/binaryen.tar.gz -C /tmp
cp "/tmp/binaryen-${BINARYEN_VERSION}/bin/wasm-merge" "/tmp/binaryen-${BINARYEN_VERSION}/bin/wasm-opt" "$GITHUB_WORKSPACE/pytoolchain/bin/"
cp -r "/tmp/binaryen-${BINARYEN_VERSION}/lib" "$GITHUB_WORKSPACE/pytoolchain/lib"
- name: Upload python toolchain
uses: actions/upload-artifact@v4
with:
name: py-toolchain
path: pytoolchain
include-hidden-files: true
retention-days: 1
- name: Discover examples
id: discover
run: |
examples=$(ls -d examples/python/*/ | xargs -n1 basename \
| jq -R -s -c 'split("\n") | map(select(length > 0))')
echo "examples=$examples" >> "$GITHUB_OUTPUT"
echo "matrix: $examples"
# One job per example: build it with extism-py, and run its scenario tests
# when it ships a __tests__/.
example:
needs: toolchain
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
example: ${{ fromJSON(needs.toolchain.outputs.examples) }}
name: py example (${{ matrix.example }})
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Restore python toolchain
uses: actions/download-artifact@v4
with:
name: py-toolchain
path: pytoolchain
# Artifact download drops the executable bit; restore it, and put the
# extism-py engine where it expects to find it.
- name: Set up toolchain
run: |
chmod +x pytoolchain/bin/*
mkdir -p "$HOME/.local/share"
cp -r pytoolchain/share/extism-py "$HOME/.local/share/extism-py"
- name: Build + test
working-directory: examples/python/${{ matrix.example }}
env:
PATH_PREFIX: ${{ github.workspace }}/pytoolchain/bin
run: |
set -e
export PATH="$PATH_PREFIX:$PATH"
export LD_LIBRARY_PATH="$GITHUB_WORKSPACE/pytoolchain/lib:$LD_LIBRARY_PATH"
python3 "$GITHUB_WORKSPACE/sdks/python/owncast_plugin_build.py" .
if [ -d __tests__ ]; then
owncast-plugin-test .
else
echo "(no __tests__ — build-only)"
fi
# Smoke-test the dev server with the Python echo-bot: build it, drive a chat
# message through /_dev/chat, and confirm the bot's reply lands in the log.
serve:
needs: toolchain
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Restore python toolchain
uses: actions/download-artifact@v4
with:
name: py-toolchain
path: pytoolchain
- name: Set up toolchain
run: |
chmod +x pytoolchain/bin/*
mkdir -p "$HOME/.local/share"
cp -r pytoolchain/share/extism-py "$HOME/.local/share/extism-py"
- name: Smoke-test owncast-plugin-serve
working-directory: examples/python/echo-bot
run: |
set -e
export PATH="$GITHUB_WORKSPACE/pytoolchain/bin:$PATH"
export LD_LIBRARY_PATH="$GITHUB_WORKSPACE/pytoolchain/lib:$LD_LIBRARY_PATH"
python3 "$GITHUB_WORKSPACE/sdks/python/owncast_plugin_build.py" .
PORT=8099 owncast-plugin-serve . > /tmp/serve.log 2>&1 &
pid=$!
ready=
for i in $(seq 1 40); do
curl -fsS http://localhost:8099/_dev/chat >/dev/null 2>&1 && { ready=1; break; }
sleep 0.5
done
if [ -z "$ready" ]; then
echo "::error::serve smoke test: server never became ready on :8099"
cat /tmp/serve.log
kill "$pid" 2>/dev/null || true
exit 1
fi
curl -fsS -X POST http://localhost:8099/_dev/chat \
-H 'Content-Type: application/json' \
-d '{"user":"alice","body":"hi"}' >/dev/null
log=$(curl -fsS http://localhost:8099/_dev/chat)
kill "$pid" 2>/dev/null || true
echo "$log"
echo "$log" | grep -q 'alice said: hi' || {
echo "::error::serve smoke test: bot reply not found in chat log"
cat /tmp/serve.log
exit 1
}