diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..233172d --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + + - package-ecosystem: "cargo" + directory: "/" + schedule: + interval: "daily" + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..861d58d --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,69 @@ +name: Build + +on: + push: + branches: + - main + - release-* + pull_request: + branches: + - main + - release-* + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + env: + RUST_LOG: info + + steps: + - uses: actions/checkout@v4 + name: Checkout Repository + + - name: Install Protoc + uses: arduino/setup-protoc@v2 + + - uses: dtolnay/rust-toolchain@stable + + - uses: Swatinem/rust-cache@v2 + name: Enable Rust Caching + + - name: Format Check + run: cargo fmt -- --check + + - name: Audit + run: cargo audit --ignore RUSTSEC-2023-0018 --ignore RUSTSEC-2023-0052 --ignore RUSTSEC-2023-0065 + + - name: Lint + run: | + cargo clippy --workspace --release + + - name: Build + # Build in release without `testing` feature. + run: | + cargo build --workspace --release + + - name: Test + # Build test binary with `testing` feature + run: | + cargo test --workspace --release --all-features --no-run + cargo test --workspace --release --all-features --verbose -- --test-threads 2 + timeout-minutes: 60 + + - name: Generate Documentation + run: | + cargo doc --no-deps --lib --release + echo '' > target/doc/index.html + + - name: Deploy Documentation + uses: peaceiris/actions-gh-pages@v3 + if: ${{ github.ref == 'refs/heads/main' }} + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./target/doc + cname: versioned-binary-serialization.docs.espressosys.com diff --git a/.github/workflows/build_nix.yml b/.github/workflows/build_nix.yml new file mode 100644 index 0000000..d39ea42 --- /dev/null +++ b/.github/workflows/build_nix.yml @@ -0,0 +1,46 @@ +name: Nix + +on: + push: + branches: + - main + - release-* + schedule: + - cron: '0 0 * * 1' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + nix: + runs-on: ubuntu-latest + timeout-minutes: 90 + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Install Nix + uses: cachix/install-nix-action@v24 + + # - uses: cachix/cachix-action@v12 + # with: + # name: espresso-systems-private + # authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + + - name: Cache cargo + uses: actions/cache@v3.3.2 + with: + path: | + ~/.cargo-nix/registry/index + ~/.cargo-nix/registry/cache + ~/.cargo-nix/git + target + key: espresso-nix-v2-${{ hashFiles('Cargo.lock') }} + + - name: "Sanity Check: nix environment loads" + run: nix-shell --run "echo Success" + + - name: "Sanity Check: nix environment builds all targets" + run: nix-shell --run "cargo build --all-targets --all-features --release --workspace" diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build_windows.yml new file mode 100644 index 0000000..2f2b2c8 --- /dev/null +++ b/.github/workflows/build_windows.yml @@ -0,0 +1,55 @@ +# Copyright (c) 2022 Espresso Systems (espressosys.com) +# This file is part of the Tide Disco library. +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU +# General Public License as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# You should have received a copy of the GNU General Public License along with this program. If not, +# see . + +name: Windows build + +on: + push: + branches: + - main + - release-* + pull_request: + branches: + - main + - release-* + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + windows: + runs-on: windows-latest + env: + RUST_LOG: info + steps: + - uses: dtolnay/rust-toolchain@stable + + - name: Install Protoc + uses: arduino/setup-protoc@v2 + + - name: Checkout Repository + uses: actions/checkout@v4 + + - uses: Swatinem/rust-cache@v2 + name: Enable Rust Caching + + - name: Build + run: | + cargo build --workspace --release + + - name: Test + run: | + cargo test --workspace --release --all-features --no-run + cargo test --workspace --release --all-features --verbose -- --test-threads 2 + timeout-minutes: 60 diff --git a/.github/workflows/debug_build.yml b/.github/workflows/debug_build.yml new file mode 100644 index 0000000..77197ef --- /dev/null +++ b/.github/workflows/debug_build.yml @@ -0,0 +1,33 @@ +name: Debug Build + +on: + schedule: + - cron: "0 0 * * *" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + env: + RUST_LOG: info + steps: + - uses: dtolnay/rust-toolchain@stable + + - uses: actions/checkout@v4 + name: Checkout Repository + + - uses: Swatinem/rust-cache@v2 + name: Enable Rust Caching + + - name: Build + run: | + cargo build --workspace --all-features + + - name: Test + run: | + cargo test --workspace --all-features --no-run + cargo test --workspace --all-features --verbose -- --test-threads 2 + timeout-minutes: 60 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..7da56bd --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,46 @@ +name: Lint + +on: + push: + branches: + - main + - release-* + pull_request: + branches: + - main + - release-* + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + + +jobs: + lint: + runs-on: ubuntu-latest + strategy: + matrix: + # Lint with many combinations of feature flags + features: + # No optional features + - '' + env: + RUST_LOG: info + steps: + - uses: actions/checkout@v4 + name: Checkout Repository + + - name: Install Protoc + uses: arduino/setup-protoc@v2 + + - uses: dtolnay/rust-toolchain@stable + + - uses: Swatinem/rust-cache@v2 + name: Enable Rust Caching + + - uses: actions-rs/clippy-check@v1 + name: Clippy + with: + token: ${{ github.token }} + args: --workspace --no-default-features --features "${{ matrix.features }}" -- -D warnings diff --git a/.github/workflows/update_nix.yml b/.github/workflows/update_nix.yml new file mode 100644 index 0000000..8affd87 --- /dev/null +++ b/.github/workflows/update_nix.yml @@ -0,0 +1,26 @@ +name: update-flake-lock + +on: + workflow_dispatch: # allows manual triggering + schedule: + - cron: '0 0 * * 0' # runs weekly on Sunday at 00:00 + +jobs: + lockfile: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Nix + uses: cachix/install-nix-action@v24 + + - uses: cachix/cachix-action@v13 + with: + name: espresso-systems-private + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + + - name: Update flake.lock + uses: DeterminateSystems/update-flake-lock@v20 + with: + pr-title: "Weekly PR to bump flake.nix" # Title of PR to be created diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..8403406 --- /dev/null +++ b/flake.nix @@ -0,0 +1,192 @@ +# Copyright (c) 2022 Espresso Systems (espressosys.com) +# This file is part of the HotShot Query Service library. +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU +# General Public License as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# You should have received a copy of the GNU General Public License along with this program. If not, +# see . + +{ + description = "Versioned serialization abstraction"; + + inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + + inputs.flake-utils.url = "github:numtide/flake-utils"; + + inputs.flake-compat.url = "github:edolstra/flake-compat"; + inputs.flake-compat.flake = false; + + inputs.rust-overlay.url = "github:oxalica/rust-overlay"; + + inputs.pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix"; + inputs.pre-commit-hooks.inputs.flake-utils.follows = "flake-utils"; + inputs.pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs"; + + inputs.poetry2nixFlake = { + url = "github:nix-community/poetry2nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + outputs = { self, nixpkgs, flake-utils, rust-overlay, pre-commit-hooks, poetry2nixFlake, ... }: + flake-utils.lib.eachDefaultSystem (system: + let + overlays = [ (import rust-overlay) ]; + pkgs = import nixpkgs { inherit system overlays; }; + poetry2nix = poetry2nixFlake.lib.mkPoetry2Nix { inherit pkgs; }; + rustToolchain = pkgs.rust-bin.stable.latest.minimal.override { + extensions = [ "rustfmt" "clippy" "llvm-tools-preview" "rust-src" ]; + }; + rustDeps = with pkgs; + [ + pkg-config + openssl + bash + + curl + docker + + cargo-audit + cargo-edit + cargo-udeps + cargo-sort + cmake + + # `postgresql` defaults to an older version (15), so we select the latest version (16) + # explicitly. + postgresql_16 + ] ++ lib.optionals stdenv.isDarwin [ + darwin.apple_sdk.frameworks.Security + darwin.apple_sdk.frameworks.CoreFoundation + darwin.apple_sdk.frameworks.SystemConfiguration + + # https://github.com/NixOS/nixpkgs/issues/126182 + libiconv + ] ++ lib.optionals (!stdenv.isDarwin) [ + cargo-watch # broken: https://github.com/NixOS/nixpkgs/issues/146349 + ]; + # nixWithFlakes allows pre v2.4 nix installations to use + # flake commands (like `nix flake update`) + nixWithFlakes = pkgs.writeShellScriptBin "nix" '' + exec ${pkgs.nixFlakes}/bin/nix --experimental-features "nix-command flakes" "$@" + ''; + cargo-llvm-cov = pkgs.rustPlatform.buildRustPackage rec { + pname = "cargo-llvm-cov"; + version = "0.5.0"; + + doCheck = false; + + buildInputs = [ pkgs.libllvm ]; + + src = builtins.fetchTarball { + url = + "https://crates.io/api/v1/crates/${pname}/${version}/download"; + sha256 = + "sha256:1a0grmpcjnqrz5c9jjbk07705py4573pmq0jcgr9m7l5xf4g1yc9"; + }; + + cargoSha256 = "sha256-11xNgiOw0qysTWpoKAXQ5gx1uJSAsp+aDDir0zpkpeQ="; + meta = with pkgs.lib; { + description = "Cargo llvm cov generates code coverage via llvm."; + homepage = "https://github.com/taiki-e/cargo-llvm-cov"; + + license = with licenses; [ mit asl20 ]; + }; + }; + pythonEnv = poetry2nix.mkPoetryEnv { projectDir = ./.; }; + myPython = with pkgs; [ poetry pythonEnv ]; + shellHook = '' + # Prevent cargo aliases from using programs in `~/.cargo` to avoid conflicts with rustup + # installations. + export CARGO_HOME=$HOME/.cargo-nix + export PATH="$PWD/$CARGO_TARGET_DIR/release:$PATH" + ''; + + RUST_SRC_PATH = "${rustToolchain}/lib/rustlib/src/rust/library"; + RUST_BACKTRACE = 1; + RUST_LOG = "info"; + RUSTFLAGS=""; + in { + checks = { + pre-commit-check = pre-commit-hooks.lib.${system}.run { + src = ./.; + hooks = { + cargo-fmt = { + enable = true; + description = "Enforce rustfmt"; + entry = "cargo fmt --all -- --check"; + pass_filenames = false; + }; + cargo-sort = { + enable = true; + description = "Ensure Cargo.toml are sorted"; + entry = "cargo sort -g -w"; + pass_filenames = false; + }; + cargo-clippy = { + enable = true; + description = "Run clippy"; + entry = "cargo clippy --workspace --all-features --all-targets -- -D clippy::dbg-macro"; + pass_filenames = false; + }; + license-header-c-style = { + enable = true; + description = + "Ensure files with c-style comments have license header"; + entry = '' + insert_license --license-filepath .license-header.txt --comment-style "//"''; + types_or = [ "rust" ]; + pass_filenames = true; + }; + license-header-hash = { + enable = true; + description = + "Ensure files with hash style comments have license header"; + entry = '' + insert_license --license-filepath .license-header.txt --comment-style "#"''; + types_or = [ "bash" "python" "toml" "nix" ]; + excludes = [ "poetry.lock" ]; + pass_filenames = true; + }; + license-header-html = { + enable = true; + description = "Ensure markdown files have license header"; + entry = '' + insert_license --license-filepath .license-header.txt --comment-style ""''; + types_or = [ "markdown" ]; + pass_filenames = true; + }; + }; + }; + }; + devShell = pkgs.mkShell { + shellHook = shellHook + # install pre-commit hooks + + self.checks.${system}.pre-commit-check.shellHook; + buildInputs = with pkgs; + [ + rust-bin.nightly.latest.rust-analyzer + nixWithFlakes + nixpkgs-fmt + git + mdbook # make-doc, documentation generation + protobuf + rustToolchain + ] ++ myPython ++ rustDeps; + + inherit RUST_SRC_PATH RUST_BACKTRACE RUST_LOG RUSTFLAGS; + }; + devShells = { + perfShell = pkgs.mkShell { + shellHook = shellHook; + buildInputs = with pkgs; + [ nixWithFlakes cargo-llvm-cov rustToolchain protobuf ] ++ rustDeps; + + inherit RUST_SRC_PATH RUST_BACKTRACE RUST_LOG RUSTFLAGS; + }; + }; + }); +}