Documentation
Release Guide
This guide explains how to create a new release of the ad-blocking repository with automatically built binaries.
Overview
The repository uses GitHub Actions to automatically build and attach binaries to releases when a new version tag is pushed. The release workflow (release.yml) builds the coordinated, multi-language binary bundle:
- Bloqr.Compiler.Dotnet.Console - .NET rules compiler console app (Windows, Linux, macOS)
- Bloqr.Dashboard.Console - .NET Dashboard app (Windows, Linux, macOS)
- bloqr-compiler - Rust rules compiler (Windows, Linux, macOS)
- bloqr-validator - native validation library and its
bloqr-validateCLI (Windows, Linux, macOS)
AdGuard.ConsoleUI (the API client console UI) moved to
BloqrAI/bloqr-apiclients— see that repo's own releases for it.
NuGet and crates.io publish independently, not as part of this release. Bloqr.Compiler.Abstractions/Bloqr.Compiler.Core (NuGet, via publish-nuget.yml) and bloqr-validator-core (crates.io, via publish-crates.yml) each have their own path-filtered workflow that publishes on every push to main touching that package's directory, or on demand via workflow_dispatch — the same pattern publish-jsr.yml already uses for @bloqr/compiler-core. See docs/architecture/nuget-distribution-strategy.md and docs/architecture/versioning-strategy.md. This keeps a library-only change from having to wait for (or force) a full binary release, and vice versa.
Creating a Release
1. Prepare the Release
Before creating a release, ensure:
- All changes are merged to the
mainbranch - All tests pass in CI/CD
- Version numbers are updated in project files if needed:
src/compilers/dotnet/src/Bloqr.Compiler.Dotnet.Console/Bloqr.Compiler.Dotnet.Console.csprojsrc/compilers/rust/cli/Cargo.toml(CLI binary version) /src/compilers/rust/core/Cargo.toml(library version)src/compilers/python/pyproject.toml
2. Create and Push a Tag
Create a new version tag following semantic versioning (e.g., v1.0.0, v1.1.0, v2.0.0-beta):
# Create a new tag
git tag -a v1.0.0 -m "Release version 1.0.0"
# Push the tag to GitHub
git push origin v1.0.0
3. Wait for the Workflow to Complete
Once the tag is pushed:
- The Release Binaries workflow will automatically start
- Monitor the workflow progress at:
https://github.com/BloqrAI/bloqr-core/actions/workflows/release.yml - The workflow will:
- Build .NET executables for Windows, Linux, and macOS
- Build Rust binaries for Windows, Linux, and macOS
- Build Python wheel package
- Create a GitHub release with all binaries attached
The complete workflow typically takes 15-20 minutes to complete all builds.
4. Verify the Release
After the workflow completes:
- Go to the Releases page
- Find your new release (e.g.,
v1.0.0) - Verify that all binaries are attached:
Bloqr.Compiler.Dotnet.Console-windows.zipBloqr.Compiler.Dotnet.Console-linux.tar.gzBloqr.Compiler.Dotnet.Console-macos.tar.gzbloqr-compiler-rust-windows.zipbloqr-compiler-rust-linux.tar.gzbloqr-compiler-rust-macos.tar.gzbloqr_compiler-*.whl(Python wheel)
5. Edit Release Notes (Optional)
The release is created with auto-generated notes. You can edit the release to:
- Add a changelog with notable changes
- Highlight breaking changes
- Add migration instructions if needed
- Reference related issues or pull requests
Build Artifacts
.NET Executables
The .NET executables are built as self-contained, single-file binaries with trimming enabled. This means:
- No .NET runtime installation required on target systems
- Single executable file per application
- Optimized size through trimming
- Includes all dependencies
Rust Binaries
The Rust binaries are built in release mode with:
- Link-Time Optimization (LTO) enabled
- Single codegen unit for maximum optimization
- Debug symbols stripped
- Minimal binary size
Python Wheel
The Python wheel package is built as a universal wheel compatible with Python 3.9+.
NuGet Packages
Bloqr.Compiler.Abstractions and Bloqr.Compiler.Core are packed with dotnet pack and pushed to GitHub Packages' NuGet feed (https://nuget.pkg.github.com/BloqrAI/index.json) by publish-nuget.yml — not by release.yml — triggered on every push to main touching src/common/dotnet/**, or manually via workflow_dispatch. Authenticated with the workflow's own GITHUB_TOKEN — no separate secret to manage. The push is idempotent (--skip-duplicate), so re-running the workflow for an already-published version is a no-op. See docs/architecture/nuget-distribution-strategy.md for why these two libraries are published while everything else in the .NET solution stays on in-repo project references.
crates.io Package
Both bloqr-validator-core (library) and bloqr-validator-core-cli (the bloqr-validate binary, installable via cargo install bloqr-validator-core-cli) are published to crates.io by publish-crates.yml — also independent of release.yml — triggered on every push to main touching either crate's directory, or manually via workflow_dispatch. The CLI job runs after the library job, since it depends on bloqr-validator-core via the registry. Authenticated via crates.io Trusted Publishing (OIDC, rust-lang/crates-io-auth-action) — no long-lived secret to manage or rotate. This briefly didn't work: this org's GitHub Enterprise account had the "Use enterprise-specific issuer URL" OIDC setting enabled, which crates.io's trusted-publishing backend rejected outright, so the workflow ran on the CARGO_REGISTRY_TOKEN secret for a short window. That Enterprise setting has since been disabled and OIDC has been live-verified end-to-end (real version bumps, real publishes) — see the auth comment block at the top of publish-crates.yml for the full history. cargo publish has no native --skip-duplicate, so the workflow checks the crates.io API for the current version before publishing to stay idempotent (the idempotency check itself needs a User-Agent header — crates.io's data-access policy 403s requests without one). bloqr-compiler-core (crates.io, the library, src/compilers/rust/core/) and bloqr-compiler (crates.io, the CLI, src/compilers/rust/cli/) are also published by publish-crates.yml, alongside the two validation crates, whenever src/compilers/rust/ changes — the CLI's binary continues to also ship via this release's GitHub Release bundle, a separate, coordinated event that doesn't gate or get gated by the crates.io publish. See docs/architecture/versioning-strategy.md.
Troubleshooting
Workflow Fails
If the release workflow fails:
- Check the workflow logs for error messages
- Common issues:
- Build failures due to compilation errors
- Missing dependencies in project files
- Network issues downloading dependencies
- Insufficient permissions (requires
contents: write)
Missing Binaries
If some binaries are missing from the release:
- Check the individual job logs in the workflow
- Verify the artifact upload steps completed successfully
- Ensure the
create-releasejob downloaded all artifacts
Rebuilding a Release
To rebuild a release:
- Delete the existing release and tag from GitHub
- Delete the local tag:
git tag -d v1.0.0 - Create a new tag and push again
Manual Release (Alternative)
If the automated workflow is not working, you can manually build and release:
Build .NET Executables
# Bloqr Compiler Console
cd src/compilers/dotnet/src/Bloqr.Compiler.Dotnet.Console
dotnet publish -c Release -r win-x64 --self-contained -p:PublishSingleFile=true -o ./publish/win-x64
dotnet publish -c Release -r linux-x64 --self-contained -p:PublishSingleFile=true -o ./publish/linux-x64
dotnet publish -c Release -r osx-x64 --self-contained -p:PublishSingleFile=true -o ./publish/osx-x64
Build Rust Binary
cd src/compilers/rust/cli
cargo build --release --target x86_64-unknown-linux-gnu
cargo build --release --target x86_64-pc-windows-msvc
cargo build --release --target x86_64-apple-darwin
Build Python Wheel
cd src/compilers/python
python -m build
Create Release Manually
- Go to Create a new release
- Choose your tag
- Add release notes
- Upload all the built binaries
- Publish the release
Best Practices
- Version Numbering: Follow Semantic Versioning
- MAJOR version for incompatible API changes
- MINOR version for new functionality in a backwards compatible manner
- PATCH version for backwards compatible bug fixes
- Pre-releases: Use tags like
v1.0.0-beta,v1.0.0-rc1for pre-releases - Testing: Test the built binaries on all platforms before announcing the release
- Documentation: Update the main README.md with notable changes
- Changelog: Consider maintaining a CHANGELOG.md file
Related Files
.github/workflows/release.yml- Coordinated multi-language binary release workflow.github/workflows/publish-nuget.yml- Independent, path-filtered NuGet publish for the common .NET library.github/workflows/publish-crates.yml- Independent, path-filtered crates.io publish forbloqr-validator-core/-cliandbloqr-compiler-core/bloqr-compilersrc/compilers/dotnet/src/Bloqr.Compiler.Dotnet.Console/Bloqr.Compiler.Dotnet.Console.csproj- .NET Compiler projectsrc/compilers/rust/cli/Cargo.toml/src/compilers/rust/core/Cargo.toml- Rust project configurationsrc/compilers/python/pyproject.toml- Python project configurationdocs/architecture/nuget-distribution-strategy.md- NuGet publishing decision record for the common .NET librarydocs/architecture/versioning-strategy.md- Per-package versioning standard (JSR, crates.io, NuGet)
Support
If you encounter issues with releases, please:
- Check existing GitHub Issues
- Review the Actions workflow runs
- Create a new issue with detailed logs if needed