Releases follow the same tag-gated Hex publishing flow as the Emerge video-interop libraries.
Pushing a v* tag to emerge-elixir/membrane_video_transcode runs the full CI matrix, validates
the release tag, and publishes the package and documentation through the GitHub hex environment.
Branch pushes, pull requests, forks, and workflow_dispatch runs only validate; they do not publish.
The pipeline in .github/workflows/ci.yml is:
check: formatting, Elixir/Rust builds and tests, docs, and the isolated Hex consumer smoke test.release-tag: require the exact checked-out tag to match both Mix and Cargo versions and a dated changelog entry.publish-hex: wait for anyhexenvironment approval, revalidate the tag, build the package and docs, then publish them separately usingHEX_API_KEY. Releases for the same tag are serialized and are not cancelled by newer runs.
This is a source-only Hex release. There are no precompiled NIF assets or crates.io publishing jobs.
Scope and prerequisites
- The first release is
0.1.0, a source-built, Linux-only decoder package. Do not advertise encoders, composed transcoding, macOS/Windows, or precompiled NIFs. - Raspberry Pi support is unvalidated in
0.1.0. Its build integration remains included, but Raspberry Pi target builds, all-features checks, and hardware qualification are not release gates for this version. Keep this limitation visible in the README and changelog. - Use the Elixir/OTP versions in
.tool-versions, Rust 1.91+, and the native prerequisites in the README. - Confirm package ownership/name availability on Hex and access to the GitHub repository.
Existing modules under
Membrane.*must not conflict with other plugins in the consuming app. - Review the Apache-2.0 license and the licenses of any native libraries being distributed. FFmpeg is supplied by the system, not bundled in this package.
One-time GitHub setup
- Create a GitHub Actions environment named
hex, matching the sibling Emerge libraries. - Configure required reviewers if releases should wait for maintainer approval. Restrict the
environment's deployment policy to release tags (
v*); the workflow also checks the repository and requires a tag-push event. - Store a Hex publishing key as the environment secret
HEX_API_KEY(a repository secret with the same name also works). Grant it publishing access for this package; never commit it. - Protect release tags against deletion or movement. The workflow checks out the triggering commit and verifies that the release tag still points to it, including after an approval wait.
The workflow's GITHUB_TOKEN needs only contents: read. It does not need a Cargo registry token
or GitHub release write access. Environment reviewers and secrets must be configured in GitHub;
the workflow file cannot create them.
Validate the release candidate
Set the intended version in
mix.exsandnative/video_decoder/Cargo.toml; refresh the native lockfile if necessary. Replace the unreleasedCHANGELOG.mdheading with a dated entry in the format## 0.1.0 - YYYY-MM-DD, using the intended version and actual release date. Keep the README dependency example in sync with the release series. An unreleased heading intentionally blocks publication.Fetch dependencies and run the checks from the repository root:
mix deps.get mix format --check-formatted mix compile --warnings-as-errors mix test mix docs --warnings-as-errors cargo fmt --manifest-path native/video_decoder/Cargo.toml --all -- --check cargo test --manifest-path native/video_decoder/Cargo.toml --locked cargo clippy --manifest-path native/video_decoder/Cargo.toml --locked --all-targets -- -D warnings cargo build --manifest-path native/video_decoder/Cargo.toml --locked --release bash scripts/check_package.shThe package smoke test builds the actual Hex archive, checks required sources and excludes compiled artifacts, then compiles an isolated production consumer against its extracted contents. It resolves Hex dependencies without the repository's
mix.lockand loads the NIF to initialize/flush/close both software codecs. It needs network access to Hex and crates.io, but no hardware device. It does not test actual video decoding or hardware interoperability.On hardware being qualified for this release (excluding Raspberry Pi), decode representative H.264/H.265 streams, verify raw output and DMA-BUF import/fence handling, and exercise EOS, held-frame backpressure, abandonment, and shutdown. Record the FFmpeg build, GPU/driver, kernel, and target tested. CI does not certify VAAPI or V4L2 hardware support. The Raspberry Pi 5 checklist is retained for future qualification only.
Inspect the payload and rendered docs before publishing:
mix hex.build --unpack --output /tmp/membrane_video_transcode-releaseUse a fresh output directory. The package must include Elixir source, the native crate source,
Cargo.toml,Cargo.lock, README, license, changelog, and guides. It must not containpriv/nativebinaries, nativetarget,_build,deps, credentials, or local paths. Opendoc/index.htmland check examples, API links, and versioned source links.
Publish a tagged release (maintainer only)
After CI and in-scope hardware qualification pass and the release changes are committed
(Raspberry Pi qualification is not required for 0.1.0):
Create an annotated tag on the reviewed release commit and validate it locally:
git tag -a v0.1.0 -m "Release 0.1.0" bash scripts/check_release.sh v0.1.0Use the intended release version. ExDoc source links use this tag, so it must point to the published commit. The validation script does not publish anything.
Push the tag with
git push origin v0.1.0. This starts the publishing pipeline. The tag must pass the complete CI matrix and the release-version/changelog gate before publishing.Review the tagged CI run and approve the
hexenvironment deployment if required. Without configured reviewers, publication proceeds automatically after validation. CI publishes to public Hex withmix hex.publish package --yes, followed bymix hex.publish docs --yes.Verify the release on Hex and HexDocs, and install it in a fresh application using only
{:membrane_video_transcode, "~> 0.1.0"}. Compile and run on a supported Linux host.
Do not move a published tag or publish locally while its CI release job is running. Version bumps, changelog dates, hardware qualification, and any configured approval remain maintainer actions.
Recovery and local dry runs
Failures before publication can be corrected before tagging, or retried using GitHub's failed-job
rerun for a transient failure. The manual workflow_dispatch trigger only reruns validation; it
is not a way to bypass the release gates.
If the package was published but the documentation step failed, do not blindly rerun the package
publication. Check out the exact release tag, fetch dependencies, regenerate the docs, and publish
only the docs with mix hex.publish docs using maintainer authentication. Check Hex first when a
publish step's result is uncertain.
For local validation without uploading, use mix hex.publish --dry-run. Some Hex versions require
mix hex.user auth even for a dry run; unauthenticated CI uses mix hex.build and mix docs.
Never commit credentials. Do not publish with MIX_ENV=prod: ExDoc is a development-only dependency.