-
Notifications
You must be signed in to change notification settings - Fork 0
215 lines (192 loc) · 8.62 KB
/
Copy pathdeploy-picomesh-yemu-demo.yml
File metadata and controls
215 lines (192 loc) · 8.62 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
name: Deploy picomesh-yemu browser demo to GitHub Pages
# Builds the full picomesh-yemu wasm demo and publishes it to GitHub Pages
# under the repository's Pages site. The deployed page boots a riscv64
# Alpine VM in the visitor's browser via TinyEMU wasm, with the picomesh
# mesh (gateway + 11 backends) launching inside that VM. No yetty
# dependency — kernel + opensbi are built from this repo's 3rdparty
# recipes, alpine minirootfs comes straight from dl-cdn.alpinelinux.org.
#
# Trigger: tag push `picomesh-<x.y.z>[-<pre>]`, plus manual dispatch.
# 3rdparty (the linked C libs plus the riscv64 kernel + opensbi firmware)
# is pulled as prebuilt release assets published by the build-3rdparty-*
# workflows — so a run is ~3 minutes with no from-source 3rdparty build,
# unless a release is missing for the pinned version (then it falls back
# to building that recipe locally).
on:
push:
tags:
# Release tags only: picomesh-<major>.<minor>.<patch>[-<pre>], e.g.
# picomesh-0.1.0, picomesh-1.2.3, picomesh-0.4.0-rc1. Pushes to main do
# not auto-deploy — the Pages site only updates when the
# maintainer cuts a tag. Manual dispatch from the Actions UI
# is still available for ad-hoc previews.
- 'picomesh-[0-9]+.[0-9]+.[0-9]+'
- 'picomesh-[0-9]+.[0-9]+.[0-9]+-*'
workflow_dispatch: {}
# Concurrency: skip in-flight runs when a newer push arrives. Pages
# itself only allows one in-flight deploy per env.
concurrency:
group: pages
cancel-in-progress: false
permissions:
contents: read
pages: write
id-token: write
env:
# 64 MiB rootfs — alpine minirootfs (~8 MiB) + picomesh static binary
# (~7 MiB) + 49 MiB free space for runtime sqlite/mdbx state. Keeps
# the wasm asset under the 100 MiB GitHub Pages soft limit.
DISK_MIB: 64
jobs:
build:
name: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# We don't depend on history (no submodules); a shallow
# clone is enough.
fetch-depth: 1
- name: install build deps
run: |
sudo apt-get update -y
sudo apt-get install -y --no-install-recommends \
build-essential cmake ninja-build clang \
gcc-riscv64-linux-gnu g++-riscv64-linux-gnu binutils-riscv64-linux-gnu \
qemu-system-misc qemu-utils \
e2fsprogs util-linux curl tar python3 \
bc bison flex libssl-dev libelf-dev cpio rsync
# The yclass codegen runs `uv run codegen.py`. Without uv on PATH
# the cmake custom command `cmake -E env ... uv run ...` dies with
# a bare "No such file or directory" before any codegen happens.
- name: install uv
uses: astral-sh/setup-uv@v5
- name: diagnose toolchain
run: |
# ubuntu-latest ships /snap/bin/cmake early in PATH as a snapd
# stub that's non-executable for the runner user; the
# setup-emsdk action that runs next prepends emsdk paths too,
# so apt's /usr/bin/cmake ends up shadowed twice. Make us
# immune to PATH games by pinning CMAKE to the absolute path
# we just installed and exporting it for every subsequent
# step via GITHUB_ENV.
set -x
which -a cmake || true
ls -l /usr/bin/cmake /usr/local/bin/cmake /snap/bin/cmake 2>&1 || true
/usr/bin/cmake --version
echo "CMAKE=/usr/bin/cmake" >> "$GITHUB_ENV"
echo "MAKE_OVERRIDES=CMAKE=/usr/bin/cmake" >> "$GITHUB_ENV"
- name: install emsdk
uses: mymindstorm/setup-emsdk@v14
with:
version: 3.1.74
actions-cache-folder: 'emsdk-cache-3.1.74'
# ----- caches -----
# Recipe-tarball cache. Keyed on the version files of each
# recipe so a bump invalidates exactly what changed, nothing
# else. The user-cache (~/.cache/picomesh-3rdparty) holds source
# tarballs (linux-7.0.tar.gz, opensbi-v1.4.tar.gz) — those
# don't change unless the version bumps.
- name: cache 3rdparty tarballs (~/.cache/picomesh-3rdparty)
uses: actions/cache@v4
with:
path: ~/.cache/picomesh-3rdparty
key: picomesh-3rdparty-cache-v1-${{ hashFiles('build-tools/3rdparty/*/version', 'build-tools/3rdparty/*/_build.sh', 'build-tools/3rdparty/linux/linux-kernel-*.config') }}
restore-keys: |
picomesh-3rdparty-cache-v1-
# Built 3rdparty outputs (already extracted, ready to use).
# Same cache key as above — if the user-cache hits, this hits
# too and we skip the actual build step.
- name: cache built 3rdparty (build-yemu-release/3rdparty + 3rdparty-cache)
uses: actions/cache@v4
with:
path: |
build-yemu-release/3rdparty
build-yemu-release/3rdparty-cache
key: picomesh-yemu-3rdparty-build-v1-${{ hashFiles('build-tools/3rdparty/*/version', 'build-tools/3rdparty/*/_build.sh', 'build-tools/3rdparty/linux/linux-kernel-*.config') }}
# ----- picomesh host + cross builds -----
# $MAKE_OVERRIDES carries CMAKE=/usr/bin/cmake set by the
# `diagnose toolchain` step above. Without it, `make` would call
# the snap-shimmed `cmake` and fall over with permission denied.
- name: build picomesh host (build-desktop-release)
run: make $MAKE_OVERRIDES build-desktop-release
- name: build picomesh riscv64 (build-linux-riscv64-release)
run: make $MAKE_OVERRIDES build-linux-riscv64-release
- name: stage build-deploy/
run: make $MAKE_OVERRIDES build-deploy
# ----- yemu rootfs (this triggers the local linux+opensbi recipes
# AND fetches alpine minirootfs from alpinelinux.org) -----
- name: bake yemu rootfs
run: |
# sudo on GitHub-hosted runners is passwordless for the
# runner user — losetup + mount work without prompting.
make $MAKE_OVERRIDES build-yemu-release
- name: shrink alpine-rootfs.img
run: |
# The image was created with truncate -s ${DISK_MIB} MiB; if
# the actual content is smaller we can shrink to fit and
# keep the deployed asset small.
IMG=build-yemu-release/alpine-rootfs.img
sudo e2fsck -fy "$IMG" || true
sudo resize2fs -M "$IMG" || true
# Truncate trailing zero pages so the wire size matches the
# actual ext4 footprint.
BLOCKS=$(sudo dumpe2fs -h "$IMG" 2>/dev/null \
| awk '/Block count/ {print $3}')
BSIZE=$(sudo dumpe2fs -h "$IMG" 2>/dev/null \
| awk '/Block size/ {print $3}')
SIZE=$(( BLOCKS * BSIZE ))
echo "shrinking to ${SIZE} bytes (${BLOCKS} blocks @ ${BSIZE}B)"
truncate -s "$SIZE" "$IMG"
ls -lh "$IMG"
# ----- webasm bundle -----
- name: build wasm bundle
run: make $MAKE_OVERRIDES build-webasm-yemu-release
- name: list deploy contents
run: |
du -sh build-webasm-yemu-release/
ls -lh build-webasm-yemu-release/
ls -lh build-webasm-yemu-release/assets/
# ----- Pages deploy -----
- uses: actions/configure-pages@v5
# Publish ONLY the web deliverables, not the whole build tree.
# Uploading build-webasm-yemu-release/ verbatim dragged the CMake
# intermediates (CMakeFiles/, *.o, libtinyemu.a, generated *.c, the
# tinyemu-include/ headers, Makefile, CMakeCache.txt) into the Pages
# artifact — bloating it and exposing build internals on a public
# site. Stage a clean _site/ with exactly what index.html and
# tinyemu-iframe.html load at runtime.
- name: stage Pages site
run: |
set -euo pipefail
SRC=build-webasm-yemu-release
DEST=_site
rm -rf "$DEST"
mkdir -p "$DEST/assets"
cp "$SRC/index.html" \
"$SRC/tinyemu-iframe.html" \
"$SRC/picomesh-yemu.js" \
"$SRC/picomesh-yemu.wasm" \
"$SRC/picomesh.cfg" \
"$DEST/"
cp "$SRC/assets/alpine-rootfs.img" \
"$SRC/assets/kernel-riscv64.bin" \
"$SRC/assets/opensbi-fw_jump.elf" \
"$DEST/assets/"
echo "staged Pages site:"
du -sh "$DEST"
find "$DEST" -type f -printf '%10s %p\n'
- name: upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: _site
deploy:
name: deploy
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4