m-bus-parser 0.1.2

A library for parsing M-Bus frames
Documentation
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