name: Rust
on:
push:
branches: [main]
tags:
- 'v*'
- 'cli-v*'
- 'wasm-v*'
pull_request:
branches: [main]
workflow_dispatch:
jobs:
build-library:
runs-on: ubuntu-latest
if: github.event_name == 'push' || github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v4
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Check Formatting
run: cargo fmt -- --check
- name: Security audit
run: |
cargo install cargo-audit
cargo audit
- name: Build Library
run: cargo build --verbose
- name: Run Library Tests
run: |
cargo test --verbose
cargo test --verbose -F std
- name: Run Library Tests with plaintext before with enabled
run: cargo test --verbose -F plaintext-before-extension
- name: Lint with Clippy
run: |
rustup component add clippy
cargo clippy -- -D warnings
build-cli:
runs-on: ubuntu-latest
if: github.event_name == 'push' || github.event_name == 'pull_request'
needs: build-library
steps:
- uses: actions/checkout@v4
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Check CLI Formatting
run: |
cd cli
cargo fmt -- --check
- name: Build CLI
run: |
cd cli
cargo build --verbose
- name: Run CLI Tests
run: |
cd cli
cargo test --verbose
- name: Lint CLI with Clippy
run: |
rustup component add clippy
cd cli
cargo clippy -- -D warnings
build-wasm:
runs-on: ubuntu-latest
if: github.event_name == 'push' || github.event_name == 'pull_request'
needs: build-library
steps:
- uses: actions/checkout@v4
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Check WASM Formatting
run: |
cd wasm
cargo fmt -- --check
- name: Build WASM
run: |
cd wasm
cargo build --verbose
- name: Run WASM Tests
run: |
cd wasm
cargo test --verbose
- name: Lint WASM with Clippy
run: |
rustup component add clippy
cd wasm
cargo clippy -- -D warnings
publish-library:
needs: build-library
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v4
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- uses: rust-lang/crates-io-auth-action@v1
id: auth
- name: Publish Library to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
RELEASE_REF_NAME: ${{ github.ref_name }}
run: |
set -euo pipefail
VERSION="${RELEASE_REF_NAME#v}"
CRATES_USER_AGENT="m-bus-parser-release-workflow (https://github.com/maebli/m-bus-parser)"
crate_exists() {
curl -fsS -A "$CRATES_USER_AGENT" "https://crates.io/api/v1/crates/$1/$VERSION" >/dev/null
}
wait_for_crate() {
crate="$1"
for _ in {1..40}; do
if crate_exists "$crate"; then
return 0
fi
sleep 15
done
echo "$crate $VERSION did not appear on crates.io"
return 1
}
publish_crate() {
crate="$1"
manifest="$2"
if crate_exists "$crate"; then
echo "$crate $VERSION is already published"
return 0
fi
cargo publish --manifest-path "$manifest"
wait_for_crate "$crate"
}
publish_crate m-bus-core crates/m-bus-core/Cargo.toml
publish_crate wired-mbus-link-layer crates/wired-mbus-link-layer/Cargo.toml
publish_crate wireless-mbus-link-layer crates/wireless-mbus-link-layer/Cargo.toml
publish_crate m-bus-application-layer crates/m-bus-application-layer/Cargo.toml
publish_crate m-bus-parser Cargo.toml
publish-cli:
needs: build-cli
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
if: startsWith(github.ref, 'refs/tags/cli-v')
steps:
- uses: actions/checkout@v4
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- uses: rust-lang/crates-io-auth-action@v1
id: auth
- name: Publish CLI to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
RELEASE_REF_NAME: ${{ github.ref_name }}
run: |
set -euo pipefail
VERSION="${RELEASE_REF_NAME#cli-v}"
CRATES_USER_AGENT="m-bus-parser-release-workflow (https://github.com/maebli/m-bus-parser)"
crate_exists() {
curl -fsS -A "$CRATES_USER_AGENT" "https://crates.io/api/v1/crates/$1/$VERSION" >/dev/null
}
wait_for_crate() {
crate="$1"
for _ in {1..40}; do
if crate_exists "$crate"; then
return 0
fi
sleep 15
done
echo "$crate $VERSION did not appear on crates.io"
return 1
}
wait_for_crate m-bus-parser
if crate_exists m-bus-parser-cli; then
echo "m-bus-parser-cli $VERSION is already published"
exit 0
fi
cd cli
cargo publish
publish-wasm:
needs: build-wasm
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write
if: startsWith(github.ref, 'refs/tags/wasm-v')
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Install wasm-pack
run: cargo install wasm-pack
- name: Build wasm package
run: |
cd wasm
wasm-pack build --target bundler
- uses: actions/setup-node@v6
with:
node-version: '24'
registry-url: 'https://registry.npmjs.org'
package-manager-cache: false
- name: Install npm dependencies
run: |
cd wasm/pkg
npm install
npm ci
- name: Publish to npm
run: |
cd wasm/pkg
VERSION="$(node -e "const fs=require('fs'); console.log(JSON.parse(fs.readFileSync('package.json','utf8')).version)")"
if npm view "m-bus-parser-wasm-pack@$VERSION" version >/dev/null 2>&1; then
echo "m-bus-parser-wasm-pack $VERSION is already published"
else
npm publish --access public
fi
- name: Create new artifacts for website
run: |
rm -rf wasm/pkg
cd wasm
wasm-pack build --target web
- name: Copy wasm artifacts to docs
run: |
cp wasm/pkg/m_bus_parser_wasm_pack.js docs/
cp wasm/pkg/m_bus_parser_wasm_pack_bg.wasm docs/
cp wasm/pkg/package.json docs/
if [ -f wasm/pkg/m_bus_parser_wasm_pack_bg.js ]; then
cp wasm/pkg/m_bus_parser_wasm_pack_bg.js docs/
fi
- name: Commit updated wasm artifacts
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"
git add docs/m_bus_parser_wasm_pack.js docs/m_bus_parser_wasm_pack_bg.js docs/m_bus_parser_wasm_pack_bg.wasm docs/meter.png docs/package.json
git commit -m "Update docs wasm artifacts" || echo "No changes to commit"
git push origin HEAD:main