build(vcv): cross-platform CI + Linux dist + /next/vcv publish flow
- add .github/workflows/vcv-plugin.yml: official rack-plugin-toolchain (pinned to commit 4fd1318, Rack SDK 2.6.6, image v19) cross-builds the MEMLNaut plugin for lin-x64/win-x64/mac-x64/mac-arm64 on CI, uploads .vcvplugin artifacts, and attaches them to GitHub Releases on v* tags. - add vcv/DISTRIBUTION.md: build + publish flow, how to add CI release artifacts to meml.lnfinitemonkeys.org/next/vcv. - add vcv/.gitignore for build products (build/, dist/, *.vcvplugin, binaries). - BUILDING.md: point at DISTRIBUTION.md; note make dist supersedes Makefile.dist. Linux x64 .vcvplugin built + verified locally via make dist and published to /next/vcv (additive subdir). Windows/macOS deferred to CI per prod-host policy.
This commit is contained in:
parent
0a17b3e76e
commit
7691b9ca8c
4 changed files with 271 additions and 0 deletions
130
.github/workflows/vcv-plugin.yml
vendored
Normal file
130
.github/workflows/vcv-plugin.yml
vendored
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
name: VCV Rack plugin (cross-platform)
|
||||
|
||||
# Builds the MEMLNaut Rack 2 plugin for all four supported platforms using the
|
||||
# OFFICIAL VCVRack/rack-plugin-toolchain (the same Docker-based cross-builder the
|
||||
# VCV Library uses). The toolchain image ships the Linux/MinGW/osxcross cross-
|
||||
# compilers and the per-platform Rack SDKs, so every .vcvplugin is reproducible on
|
||||
# a single Linux runner — no per-platform native runners, no Apple hardware.
|
||||
#
|
||||
# Outputs: one <slug>-<version>-<platform>.vcvplugin per platform, uploaded as a
|
||||
# workflow artifact, and attached to a GitHub Release when triggered by a tag push
|
||||
# (v*). See vcv/DISTRIBUTION.md for the publish-to-/next/vcv flow.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, feat/manifold-mission, feat/vcv-dist]
|
||||
paths:
|
||||
- 'vcv/**'
|
||||
- '.github/workflows/vcv-plugin.yml'
|
||||
tags:
|
||||
- 'v*'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'vcv/**'
|
||||
- '.github/workflows/vcv-plugin.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
# Pin the official toolchain to a known-good commit (Rack SDK 2.6.6, docker
|
||||
# image version 19). Bump deliberately; never float on master.
|
||||
TOOLCHAIN_REPO: VCVRack/rack-plugin-toolchain
|
||||
TOOLCHAIN_REF: 4fd1318701624051cee54b385343f23d59b4845c
|
||||
TOOLCHAIN_IMAGE_VERSION: '19'
|
||||
PLUGIN_DIR_REL: vcv
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build ${{ matrix.platform }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# lin-x64 + win-x64 cross-build with gcc / mingw (no Apple SDK).
|
||||
# mac-x64 + mac-arm64 use osxcross baked into the toolchain image — this
|
||||
# is how plugins are cross-built for macOS WITHOUT Apple hardware. The
|
||||
# license-restricted macOS SDK is fetched only inside the toolchain image
|
||||
# build (never committed to this repo).
|
||||
platform: [lin-x64, win-x64, mac-x64, mac-arm64]
|
||||
|
||||
steps:
|
||||
- name: Checkout plugin
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Checkout rack-plugin-toolchain (pinned)
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ env.TOOLCHAIN_REPO }}
|
||||
ref: ${{ env.TOOLCHAIN_REF }}
|
||||
path: toolchain
|
||||
|
||||
- name: Cache toolchain Docker image
|
||||
id: img-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: /tmp/rack-toolchain-image
|
||||
key: rack-toolchain-${{ env.TOOLCHAIN_REF }}-v${{ env.TOOLCHAIN_IMAGE_VERSION }}
|
||||
|
||||
- name: Fetch per-platform Rack SDKs
|
||||
working-directory: toolchain
|
||||
run: make rack-sdk-all
|
||||
|
||||
- name: Load or build toolchain image
|
||||
working-directory: toolchain
|
||||
run: |
|
||||
set -euo pipefail
|
||||
IMG="rack-plugin-toolchain:${TOOLCHAIN_IMAGE_VERSION}"
|
||||
if [ -f /tmp/rack-toolchain-image/image.tar ]; then
|
||||
echo "Loading cached toolchain image $IMG"
|
||||
docker load -i /tmp/rack-toolchain-image/image.tar
|
||||
else
|
||||
echo "Building toolchain image $IMG (one-off; cached for later runs)"
|
||||
# rack-sdk-all already ran; build the cross-toolchain image (mingw +
|
||||
# osxcross). This is the heavy step — cached by TOOLCHAIN_REF.
|
||||
docker build --build-arg JOBS=$(nproc) \
|
||||
--tag "$IMG" . --progress=plain
|
||||
mkdir -p /tmp/rack-toolchain-image
|
||||
docker save "$IMG" -o /tmp/rack-toolchain-image/image.tar
|
||||
fi
|
||||
|
||||
- name: Build .vcvplugin for ${{ matrix.platform }}
|
||||
working-directory: toolchain
|
||||
run: |
|
||||
set -euo pipefail
|
||||
make docker-plugin-build-${{ matrix.platform }} \
|
||||
PLUGIN_DIR="${GITHUB_WORKSPACE}/${PLUGIN_DIR_REL}"
|
||||
|
||||
- name: Collect artifact
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p out
|
||||
cp toolchain/plugin-build/*.vcvplugin out/
|
||||
ls -la out
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: MEMLNaut-${{ matrix.platform }}
|
||||
path: out/*.vcvplugin
|
||||
if-no-files-found: error
|
||||
|
||||
release:
|
||||
name: Attach to release
|
||||
needs: build
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: artifacts
|
||||
merge-multiple: true
|
||||
|
||||
- name: Publish release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: artifacts/*.vcvplugin
|
||||
generate_release_notes: true
|
||||
7
vcv/.gitignore
vendored
Normal file
7
vcv/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# VCV plugin build products (see BUILDING.md / DISTRIBUTION.md)
|
||||
/build/
|
||||
/dist/
|
||||
/plugin.so
|
||||
/plugin.dylib
|
||||
/plugin.dll
|
||||
*.vcvplugin
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
# Building MEMLNaut VCV Plugin
|
||||
|
||||
> **Distribution & cross-platform builds:** for packaging `.vcvplugin` files,
|
||||
> the cross-platform CI matrix, and publishing to `/next/vcv`, see
|
||||
> [DISTRIBUTION.md](DISTRIBUTION.md). The official `make dist` target (from the
|
||||
> SDK's `plugin.mk`) produces `dist/<slug>-<version>-<platform>.vcvplugin`; the
|
||||
> legacy `Makefile.dist` (zip-based, hard-coded 0.1.0) is superseded by it.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **VCV Rack 2 SDK** — download from https://vcvrack.com/manual/PluginDevelopmentTutorial or build from source
|
||||
|
|
|
|||
128
vcv/DISTRIBUTION.md
Normal file
128
vcv/DISTRIBUTION.md
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
# Distributing the MEMLNaut VCV Rack plugin
|
||||
|
||||
How the `MEMLNaut` plugin is built for every platform and published to the public
|
||||
download page at **https://meml.lnfinitemonkeys.org/next/vcv/**.
|
||||
|
||||
Plugin slug: `MEMLNaut`. Version comes from `plugin.json` (`jq -r .version`).
|
||||
|
||||
---
|
||||
|
||||
## 1. Build artefacts (`.vcvplugin`)
|
||||
|
||||
A `.vcvplugin` is a `tar.zst` archive of a `MEMLNaut/` directory containing the
|
||||
platform binary (`plugin.so` / `.dll` / `.dylib`), `plugin.json`, and `res/`. The
|
||||
official `plugin.mk` `dist` target produces it, named
|
||||
`<slug>-<version>-<platform>.vcvplugin` (e.g. `MEMLNaut-0.2.0-lin-x64.vcvplugin`).
|
||||
Platforms: `lin-x64`, `win-x64`, `mac-x64`, `mac-arm64`.
|
||||
|
||||
### Linux x64 — locally (works today)
|
||||
|
||||
The Rack 2 SDK is installed at `$HOME/.local/share/Rack2/Rack-SDK`:
|
||||
|
||||
```bash
|
||||
cd vcv
|
||||
RACK_DIR=$HOME/.local/share/Rack2/Rack-SDK make dist
|
||||
# -> vcv/dist/MEMLNaut-<version>-lin-x64.vcvplugin
|
||||
```
|
||||
|
||||
This is the only platform we build on the server: the host toolchain is native
|
||||
Linux x64 and the SDK is already present. Build products (`build/`, `dist/`,
|
||||
`plugin.so`, `*.vcvplugin`) are git-ignored — they are publish artefacts, not
|
||||
source.
|
||||
|
||||
### Windows / macOS — cross-built on CI (NOT on the server)
|
||||
|
||||
The other three platforms are cross-built by the official
|
||||
[VCVRack/rack-plugin-toolchain](https://github.com/VCVRack/rack-plugin-toolchain),
|
||||
the same Docker cross-builder the VCV Library uses. **We do not run that toolchain
|
||||
on the production VPS** — its image build compiles mingw + osxcross and pulls the
|
||||
Apple SDK (multi-GB, multi-hour), which would overload a host that serves live
|
||||
services. macOS additionally requires the Apple SDK, which we never redistribute.
|
||||
CI is the right place for all of this; for a local-only macOS build the operator
|
||||
can use a Mac with the native SDK.
|
||||
|
||||
---
|
||||
|
||||
## 2. CI: `.github/workflows/vcv-plugin.yml`
|
||||
|
||||
Builds all four platforms on `ubuntu-latest` runners via the pinned toolchain
|
||||
(`TOOLCHAIN_REF`, currently Rack SDK 2.6.6 / toolchain image v19). Triggers on:
|
||||
|
||||
- pushes touching `vcv/**` (smoke-build the matrix),
|
||||
- pull requests touching `vcv/**`,
|
||||
- tag pushes `v*` (build **and** attach to a GitHub Release),
|
||||
- manual `workflow_dispatch`.
|
||||
|
||||
Per matrix platform the job: checks out the plugin + pinned toolchain, fetches the
|
||||
per-platform Rack SDKs (`make rack-sdk-all`), builds/loads the cached toolchain
|
||||
Docker image, then runs `make docker-plugin-build-<platform>
|
||||
PLUGIN_DIR=$GITHUB_WORKSPACE/vcv`. The resulting `.vcvplugin` is uploaded as a
|
||||
workflow artifact. On a `v*` tag the `release` job downloads all four and attaches
|
||||
them to the release via `softprops/action-gh-release`.
|
||||
|
||||
The heavy toolchain image is cached by `TOOLCHAIN_REF`, so only the first run on a
|
||||
new pin pays the build cost.
|
||||
|
||||
### Cutting a release
|
||||
|
||||
```bash
|
||||
# bump version in vcv/plugin.json, commit, then:
|
||||
git tag v0.2.0
|
||||
git push origin v0.2.0
|
||||
```
|
||||
|
||||
CI builds lin-x64 / win-x64 / mac-x64 / mac-arm64 and attaches the four
|
||||
`.vcvplugin` files to the GitHub release for `v0.2.0`.
|
||||
|
||||
### Bumping the toolchain
|
||||
|
||||
Edit `TOOLCHAIN_REF` (and `TOOLCHAIN_IMAGE_VERSION` if the image version changes)
|
||||
in `.github/workflows/vcv-plugin.yml`. Pin to a commit — never float on `master`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Publishing to `/next/vcv`
|
||||
|
||||
The download page lives in the live a-immersive docroot at
|
||||
`/home/w1n5t0n/deployments/meml-aimmersive/next/vcv/`. It is **purely additive** —
|
||||
a new subdir alongside `/next/animations`, disturbing nothing else.
|
||||
|
||||
Files:
|
||||
|
||||
- `index.html` — the download page (Manifold design tokens: dark, JetBrains Mono,
|
||||
`--accent #ff6a00`). Lists each platform with a download link, the version, VCV
|
||||
install instructions, and which platforms are available now vs built by CI.
|
||||
- `a-immersive.html` — a byte-identical copy of `index.html`. nginx for
|
||||
`meml.lnfinitemonkeys.org` sets `index a-immersive.html`, so `/next/vcv/`
|
||||
resolves via this alias (same trick `/next/animations` uses). No nginx change is
|
||||
needed for a new subdir.
|
||||
- `MEMLNaut-<version>-<platform>.vcvplugin` — the artefact(s).
|
||||
|
||||
### Adding CI release artifacts to `/next/vcv`
|
||||
|
||||
After a `v*` release builds on CI, copy the new `.vcvplugin` files into the publish
|
||||
dir and refresh the cards/links in both HTML copies:
|
||||
|
||||
```bash
|
||||
# from a checkout, with the release tag's artifacts downloaded e.g. via:
|
||||
# gh release download v0.2.0 -p '*.vcvplugin' -D /tmp/vcvrel
|
||||
PUB=/home/w1n5t0n/deployments/meml-aimmersive/next/vcv
|
||||
cp /tmp/vcvrel/*.vcvplugin "$PUB"/
|
||||
# then edit $PUB/index.html: flip the win/mac cards from "built by CI"
|
||||
# (.dl.disabled) to live download links, and copy index.html -> a-immersive.html:
|
||||
cp "$PUB/index.html" "$PUB/a-immersive.html"
|
||||
```
|
||||
|
||||
Bumping the version means updating the `v0.2.0` strings and the filenames in the
|
||||
two HTML copies. Keep `index.html` and `a-immersive.html` identical.
|
||||
|
||||
### Verify
|
||||
|
||||
```bash
|
||||
curl -sk -o /dev/null -w '%{http_code}\n' https://meml.lnfinitemonkeys.org/next/vcv/
|
||||
curl -sk -o /dev/null -w '%{http_code}\n' \
|
||||
https://meml.lnfinitemonkeys.org/next/vcv/MEMLNaut-0.2.0-lin-x64.vcvplugin
|
||||
```
|
||||
|
||||
Both should return `200`. Don't disturb `/next/`, `/next/animations/`, or the live
|
||||
a-immersive at `/`.
|
||||
Loading…
Reference in a new issue