Commit 773cacd
authored
ci: add GitHub Actions workflow for multi-platform testing (#10)
* ci: add GitHub Actions workflow for multi-platform testing
- Add CI workflow with lint job (C++, TypeScript, types, markdown)
- Add build jobs for Linux glibc (Rocky 8), Linux musl (Alpine 3.20)
- Add build jobs for macOS ARM64 (macos-14), macOS x64 (macos-13)
- Test on Node.js 20 and 22 (matching engines field)
- Use system FFmpeg via package managers for CI validation
- Add @pproenca/webcodecs-ffmpeg-* as optionalDependencies
- Update gyp/ffmpeg-paths-lib.ts to resolve FFmpeg from npm package
- Resolution order: FFMPEG_ROOT > npm package > ./ffmpeg-install > system
The CI uses --omit=optional to validate the system FFmpeg fallback works.
Developers get FFmpeg automatically on npm install, or can opt-out to use
system FFmpeg with npm install --omit=optional.
* fix(ci): use npm install instead of npm ci
The project doesn't commit package-lock.json, so npm ci fails.
Use npm install with --omit=optional to skip FFmpeg optionalDeps.
* fix(ci): use pip cpplint on Linux, fix Rocky FFmpeg install
- Install cpplint via pip (npm package doesn't support Linux)
- Enable EPEL and PowerTools repos before FFmpeg install
- Try RPMFusion as fallback if ffmpeg-devel not in EPEL
* fix(ci): don't skip optional deps for lint (biome needs them)
* fix(ci): build TS for lint:types, use Python 3.9 on Rocky
- Add npm run build:ts step before lint:types (tsd needs dist/index.d.ts)
- Use Python 3.9 on Rocky Linux 8 (node-gyp requires Python 3.8+)
- Use RPMFusion for FFmpeg on Rocky 8 (EPEL doesn't have ffmpeg-devel)
* fix(ci): use GCC Toolset 12 on Rocky, install Alpine FFmpeg deps
Linux glibc (Rocky 8):
- Install gcc-toolset-12 for C++20 support (Rocky 8 default GCC 8.x lacks -std=c++20)
- Source toolset enable script before build
Linux musl (Alpine 3.20):
- Install all FFmpeg transitive dependencies required by pkg-config
- Alpine's FFmpeg is compiled with many optional features, all need their dev packages
* fix(ci): use Rocky 9 for FFmpeg 6+, simplify Alpine FFmpeg
Rocky Linux 9:
- Switch from Rocky 8 to Rocky 9 (glibc 2.34 instead of 2.28)
- Rocky 8's RPMFusion only has FFmpeg 4.x, project requires 5.0+
- Rocky 9 RPMFusion has FFmpeg 6+ with C++20 support out of box
Alpine 3.20:
- Use pkgconf instead of pkgconfig (correct Alpine package name)
- Simplify to just ffmpeg-dev (pulls in all core dependencies)
- Add pkg-config verification step to catch errors early
* fix: add FFmpeg 5.0 compatibility for AVFrame::duration
AVFrame::duration was added in FFmpeg 5.1 (libavutil 57.28.100).
For FFmpeg 5.0, use the deprecated pkt_duration field instead.
Added AV_FRAME_DURATION and AV_FRAME_SET_DURATION macros in common.h
that select the correct field based on FFmpeg version.
* chore: commit cmake
* feat(build): harden native build configuration
- Add Linux FFmpeg fallback paths (/usr/include, /usr/local/include, /usr/lib, /usr/local/lib)
- Add RPATH for macOS (@loader_path/../lib) and Linux ($ORIGIN/../lib)
- Add MacPorts support (/opt/local/include, /opt/local/lib)
- Add dynamic linking fallback when static fails on Linux
- Add explicit error logging with [node-webcodecs] prefix
- Add pkg-config output validation (empty check)
- Add isPkgConfigAvailable() helper function
- Add -Wpedantic and -Wshadow compiler warnings
- Add Debug/Release configurations block
- Add parallel compilation (-j max) to build scripts
- Add node-gyp caching to CI workflow
- Implement rpath mode in ffmpeg-paths.js
Closes: harden-native-build-config
* fix(build): use dynamic linking for Linux pkg-config fallback
Alpine's ffmpeg-dev only provides shared libraries. The --static flag
caused pkg-config to output flags for non-existent static libraries,
which then failed at link time.
Dynamic linking works correctly for CI testing with system FFmpeg.
Static linking is only needed for distribution builds with bundled FFmpeg.
* Revert "fix(build): use dynamic linking for Linux pkg-config fallback"
This reverts commit 7b038e5.
* feat(ci): use static FFmpeg musl package for Alpine builds
- Add musl libc detection in ffmpeg-paths-lib.ts
- On musl systems, try @pproenca/webcodecs-ffmpeg-linux-x64-musl first
- Update CI to install musl FFmpeg package instead of system ffmpeg-dev
- Remove system pkg-config fallback for Alpine (use npm package only)
This enables proper static linking on Alpine Linux using the
pre-built FFmpeg package with musl libc support.
* feat: add musl FFmpeg package to optionalDependencies
npm will auto-install @pproenca/webcodecs-ffmpeg-linux-x64-musl on
Alpine/musl systems via the libc field in the package's package.json.
Simplified CI to use regular npm install instead of explicit package install.
* chore: re-trigger CI after musl FFmpeg package published
* feat(build): use npm packages for FFmpeg headers and link flags
- Add @pproenca/webcodecs-ffmpeg-dev for cross-platform headers
- Add tryResolveIncludeFromDevPackage() for header resolution
- Add tryResolveLinkFlagsFromNpmPackage() for static link flags
- Update resolution order: npm packages take precedence
- Bump FFmpeg packages to ^0.1.4 with ./link-flags export
- Update unit test for new resolution priority
This enables fully static builds from npm packages without
requiring system FFmpeg or pkg-config with hardcoded paths.
* fix(ci): add zlib-dev and bzip2-dev for Alpine musl builds
FFmpeg linking requires system compression libraries (-lz, -lbz2)
which were missing from the Alpine container package installation.
* fix(ci): disable LTO for Alpine musl builds
Add -fno-lto to Linux cflags_cc and ldflags to prevent LTO conflicts
with musl's fortified libc functions. The FFmpeg static libraries are
compiled with LTO, which causes link failures on Alpine due to
vsnprintf being marked always_inline in fortify headers.
* fix(ci): use npm FFmpeg packages for Linux glibc builds
- Remove ffmpeg-devel from dnf install (not needed with npm packages)
- Remove --omit=optional to install @pproenca/webcodecs-ffmpeg-* packages
The platform packages contain static FFmpeg libs and link-flags.js,
enabling fully static builds without system FFmpeg.
* feat(ci): align build matrix with ffmpeg-prebuilds packages
Expand CI from 4 builds to 10 builds matching @pproenca/webcodecs-ffmpeg:
- 5 platforms: darwin-arm64, darwin-x64, linux-x64-glibc, linux-arm64, linux-x64-musl
- 2 variants: free (LGPL), non-free (GPL)
Changes:
- Refactor to unified matrix strategy (replaces 4 separate jobs)
- Add linux-arm64 support via QEMU emulation
- Add variant-aware FFmpeg package installation
- macOS free variant uses npm packages, non-free uses Homebrew
- Linux builds explicitly install correct FFmpeg package per variant
- Update ffmpeg-prebuilds to 0.1.6
- Add linux-arm64 to optionalDependencies
- Simplify to Node.js 20 only
* fix(ci): update ffmpeg-prebuilds to 0.1.7 and add zlib/bzip2 deps
- Update @pproenca/webcodecs-ffmpeg packages to ^0.1.7 (fixes LTO issue)
- Add zlib-devel bzip2-devel to Rocky Linux builds
* fix(ci): clean npm cache before installing FFmpeg packages
Prevents stale cache from causing "Access token expired" warnings.
* fix(ci): add libatomic for Linux glibc builds
The npm FFmpeg packages include -latomic in link flags, which requires
the libatomic library to be installed for linking. This was missing
from the Rocky Linux CI containers.1 parent ca693e7 commit 773cacd
33 files changed
Lines changed: 3820 additions & 42 deletions
File tree
- .claude/skills
- dev-cmake
- assets
- references
- node-gyp
- references
- .github/workflows
- gyp
- openspec/changes
- harden-native-build-config
- specs/native-build
- introduce-ci-workflow
- specs
- ci-workflow
- optional-ffmpeg-deps
- src
- test/unit
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 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 | + | |
0 commit comments