| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- name: CICD
- env:
- CICD_INTERMEDIATES_DIR: "_cicd-intermediates"
- MSRV_FEATURES: ""
- on:
- workflow_dispatch:
- pull_request:
- push:
- branches:
- - master
- tags:
- - '*'
- jobs:
- crate_metadata:
- name: Extract crate metadata
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - name: Extract crate information
- id: crate_metadata
- run: |
- cargo metadata --no-deps --format-version 1 | jq -r '"name=" + .packages[0].name' | tee -a $GITHUB_OUTPUT
- cargo metadata --no-deps --format-version 1 | jq -r '"version=" + .packages[0].version' | tee -a $GITHUB_OUTPUT
- cargo metadata --no-deps --format-version 1 | jq -r '"maintainer=" + .packages[0].authors[0]' | tee -a $GITHUB_OUTPUT
- cargo metadata --no-deps --format-version 1 | jq -r '"homepage=" + .packages[0].homepage' | tee -a $GITHUB_OUTPUT
- cargo metadata --no-deps --format-version 1 | jq -r '"msrv=" + .packages[0].rust_version' | tee -a $GITHUB_OUTPUT
- outputs:
- name: ${{ steps.crate_metadata.outputs.name }}
- version: ${{ steps.crate_metadata.outputs.version }}
- maintainer: ${{ steps.crate_metadata.outputs.maintainer }}
- homepage: ${{ steps.crate_metadata.outputs.homepage }}
- msrv: ${{ steps.crate_metadata.outputs.msrv }}
- ensure_cargo_fmt:
- name: Ensure 'cargo fmt' has been run
- runs-on: ubuntu-20.04
- steps:
- - uses: dtolnay/rust-toolchain@stable
- with:
- components: rustfmt
- - uses: actions/checkout@v4
- - run: cargo fmt -- --check
- documentation_checks:
- name: Documentation checks
- runs-on: ubuntu-20.04
- steps:
- - uses: dtolnay/rust-toolchain@stable
- - uses: actions/checkout@v3
- - uses: actions/setup-python@v5
- - name: Install mdbook
- run: |
- cargo install mdbook
- cargo install mdbook-linkcheck
- - name: Build documentation
- run: |
- cd book
- python build.py
- if [ -n "$(git status --porcelain)" ]; then
- echo "Documentation not up to date."
- echo "Make sure to run 'build.py' in the book/ folder"
- exit 1
- fi
- wasm:
- name: WASM version
- runs-on: ubuntu-20.04
- steps:
- - uses: dtolnay/rust-toolchain@stable
- - uses: actions/checkout@v3
- - name: Install wasm-pack
- run: |
- curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- - name: Build WASM version
- run: |
- cd numbat-wasm
- bash build.sh
- - name: Test WASM version
- run: |
- cd numbat-wasm
- bash test.sh
- min_version:
- name: Minimum supported rust version
- runs-on: ubuntu-20.04
- needs: crate_metadata
- steps:
- - name: Checkout source code
- uses: actions/checkout@v4
- - name: Install rust toolchain (v${{ needs.crate_metadata.outputs.msrv }})
- uses: dtolnay/rust-toolchain@master
- with:
- toolchain: ${{ needs.crate_metadata.outputs.msrv }}
- components: clippy
- - name: Run clippy (on minimum supported rust version to prevent warnings we can't fix)
- run: cargo clippy --locked --all-targets ${{ env.MSRV_FEATURES }}
- - name: Run tests
- run: cargo test --locked ${{ env.MSRV_FEATURES }}
- build:
- name: ${{ matrix.job.target }} (${{ matrix.job.os }})
- runs-on: ${{ matrix.job.os }}
- needs: crate_metadata
- strategy:
- fail-fast: false
- matrix:
- job:
- - { target: aarch64-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true }
- - { target: arm-unknown-linux-gnueabihf , os: ubuntu-20.04, use-cross: true }
- - { target: arm-unknown-linux-musleabihf, os: ubuntu-20.04, use-cross: true }
- - { target: i686-pc-windows-msvc , os: windows-2019 }
- - { target: i686-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true }
- - { target: i686-unknown-linux-musl , os: ubuntu-20.04, use-cross: true }
- - { target: x86_64-apple-darwin , os: macos-12 }
- #- { target: x86_64-pc-windows-gnu , os: windows-2019 }
- - { target: x86_64-pc-windows-msvc , os: windows-2019 }
- - { target: x86_64-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true }
- - { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, use-cross: true }
- env:
- BUILD_CMD: cargo
- steps:
- - name: Checkout source code
- uses: actions/checkout@v4
- - name: Install prerequisites
- shell: bash
- run: |
- case ${{ matrix.job.target }} in
- arm-unknown-linux-*) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
- aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;;
- esac
- - name: Install Rust toolchain
- uses: dtolnay/rust-toolchain@stable
- with:
- targets: ${{ matrix.job.target }}
- - name: Install cross
- if: matrix.job.use-cross
- uses: taiki-e/install-action@v2
- with:
- tool: cross
- - name: Overwrite build command env variable
- if: matrix.job.use-cross
- shell: bash
- run: echo "BUILD_CMD=cross" >> $GITHUB_ENV
- - name: Show version information (Rust, cargo, GCC)
- shell: bash
- run: |
- gcc --version || true
- rustup -V
- rustup toolchain list
- rustup default
- cargo -V
- rustc -V
- - name: Build
- shell: bash
- run: $BUILD_CMD build --locked --release --target=${{ matrix.job.target }}
- - name: Set binary name & path
- id: bin
- shell: bash
- run: |
- # Figure out suffix of binary
- EXE_suffix=""
- case ${{ matrix.job.target }} in
- *-pc-windows-*) EXE_suffix=".exe" ;;
- esac;
- # Setup paths
- BIN_NAME="${{ needs.crate_metadata.outputs.name }}${EXE_suffix}"
- BIN_PATH="target/${{ matrix.job.target }}/release/${BIN_NAME}"
- # Let subsequent steps know where to find the binary
- echo "BIN_PATH=${BIN_PATH}" >> $GITHUB_OUTPUT
- echo "BIN_NAME=${BIN_NAME}" >> $GITHUB_OUTPUT
- - name: Set testing options
- id: test-options
- shell: bash
- run: |
- # test only library unit tests and binary for arm-type targets
- unset CARGO_TEST_OPTIONS
- unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--lib --bin ${{ needs.crate_metadata.outputs.name }}" ;; esac;
- echo "CARGO_TEST_OPTIONS=${CARGO_TEST_OPTIONS}" >> $GITHUB_OUTPUT
- - name: Run tests
- shell: bash
- run: $BUILD_CMD test --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}}
- - name: Create tarball
- id: package
- shell: bash
- run: |
- PKG_suffix=".tar.gz" ; case ${{ matrix.job.target }} in *-pc-windows-*) PKG_suffix=".zip" ;; esac;
- PKG_BASENAME=${{ needs.crate_metadata.outputs.name }}-v${{ needs.crate_metadata.outputs.version }}-${{ matrix.job.target }}
- PKG_NAME=${PKG_BASENAME}${PKG_suffix}
- echo "PKG_NAME=${PKG_NAME}" >> $GITHUB_OUTPUT
- PKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/package"
- ARCHIVE_DIR="${PKG_STAGING}/${PKG_BASENAME}/"
- mkdir -p "${ARCHIVE_DIR}"
- # Binary
- cp "${{ steps.bin.outputs.BIN_PATH }}" "$ARCHIVE_DIR"
- # README and LICENSE files
- cp "README.md" "LICENSE-MIT" "LICENSE-APACHE" "$ARCHIVE_DIR"
- # Desktop file and icons
- mkdir "$ARCHIVE_DIR/assets"
- cp "assets/numbat.desktop" assets/numbat-*x*.png "assets/numbat.svg" "$ARCHIVE_DIR/assets"
- # Numbat prelude
- cp -r numbat/modules "$ARCHIVE_DIR"
- # base compressed package
- pushd "${PKG_STAGING}/" >/dev/null
- case ${{ matrix.job.target }} in
- *-pc-windows-*) 7z -y a "${PKG_NAME}" "${PKG_BASENAME}"/* | tail -2 ;;
- *) tar czf "${PKG_NAME}" "${PKG_BASENAME}"/* ;;
- esac;
- popd >/dev/null
- # Let subsequent steps know where to find the compressed package
- echo "PKG_PATH=${PKG_STAGING}/${PKG_NAME}" >> $GITHUB_OUTPUT
- - name: Create Debian package
- id: debian-package
- shell: bash
- if: startsWith(matrix.job.os, 'ubuntu')
- run: |
- COPYRIGHT_YEARS="2022 - "$(date "+%Y")
- DPKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/debian-package"
- DPKG_DIR="${DPKG_STAGING}/dpkg"
- mkdir -p "${DPKG_DIR}"
- DPKG_BASENAME=${{ needs.crate_metadata.outputs.name }}
- DPKG_CONFLICTS=${{ needs.crate_metadata.outputs.name }}-musl
- case ${{ matrix.job.target }} in *-musl*) DPKG_BASENAME=${{ needs.crate_metadata.outputs.name }}-musl ; DPKG_CONFLICTS=${{ needs.crate_metadata.outputs.name }} ;; esac;
- DPKG_VERSION=${{ needs.crate_metadata.outputs.version }}
- unset DPKG_ARCH
- case ${{ matrix.job.target }} in
- aarch64-*-linux-*) DPKG_ARCH=arm64 ;;
- arm-*-linux-*hf) DPKG_ARCH=armhf ;;
- i686-*-linux-*) DPKG_ARCH=i686 ;;
- x86_64-*-linux-*) DPKG_ARCH=amd64 ;;
- *) DPKG_ARCH=notset ;;
- esac;
- DPKG_NAME="${DPKG_BASENAME}_${DPKG_VERSION}_${DPKG_ARCH}.deb"
- echo "DPKG_NAME=${DPKG_NAME}" >> $GITHUB_OUTPUT
- # Binary
- install -Dm755 "${{ steps.bin.outputs.BIN_PATH }}" "${DPKG_DIR}/usr/bin/${{ steps.bin.outputs.BIN_NAME }}"
- # README and LICENSE
- install -Dm644 "README.md" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/README.md"
- install -Dm644 "LICENSE-MIT" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/LICENSE-MIT"
- install -Dm644 "LICENSE-APACHE" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/LICENSE-APACHE"
- # Desktop file and icons
- install -Dm644 "assets/numbat.desktop" "${DPKG_DIR}/usr/share/applications/numbat.desktop"
- install -Dm644 "assets/numbat.svg" "${DPKG_DIR}/usr/share/icons/hicolor/scalable/apps/numbat.svg"
- for s in 16 22 24 32 48 64 128 256 512; do
- install -Dm644 "assets/numbat-${s}x${s}.png" "${DPKG_DIR}/usr/share/icons/hicolor/${s}x${s}/apps/numbat.png"
- done
- # Numbat prelude
- mkdir -p "${DPKG_DIR}/usr/share/${DPKG_BASENAME}"
- cp -r numbat/modules "${DPKG_DIR}/usr/share/${DPKG_BASENAME}"
- cat > "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/copyright" <<EOF
- Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
- Upstream-Name: ${{ needs.crate_metadata.outputs.name }}
- Source: ${{ needs.crate_metadata.outputs.homepage }}
- Files: *
- Copyright: ${{ needs.crate_metadata.outputs.maintainer }}
- Copyright: $COPYRIGHT_YEARS ${{ needs.crate_metadata.outputs.maintainer }}
- License: Apache-2.0 or MIT
- License: Apache-2.0
- On Debian systems, the complete text of the Apache-2.0 can be found in the
- file /usr/share/common-licenses/Apache-2.0.
- License: MIT
- Permission is hereby granted, free of charge, to any
- person obtaining a copy of this software and associated
- documentation files (the "Software"), to deal in the
- Software without restriction, including without
- limitation the rights to use, copy, modify, merge,
- publish, distribute, sublicense, and/or sell copies of
- the Software, and to permit persons to whom the Software
- is furnished to do so, subject to the following
- conditions:
- .
- The above copyright notice and this permission notice
- shall be included in all copies or substantial portions
- of the Software.
- .
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
- ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
- TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
- SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
- IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- EOF
- chmod 644 "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/copyright"
- # control file
- mkdir -p "${DPKG_DIR}/DEBIAN"
- cat > "${DPKG_DIR}/DEBIAN/control" <<EOF
- Package: ${DPKG_BASENAME}
- Version: ${DPKG_VERSION}
- Section: utils
- Priority: optional
- Maintainer: ${{ needs.crate_metadata.outputs.maintainer }}
- Homepage: ${{ needs.crate_metadata.outputs.homepage }}
- Architecture: ${DPKG_ARCH}
- Provides: ${{ needs.crate_metadata.outputs.name }}
- Conflicts: ${DPKG_CONFLICTS}
- Description: Statically typed programming language for scientific computations with first class support for physical dimensions and units
- EOF
- DPKG_PATH="${DPKG_STAGING}/${DPKG_NAME}"
- echo "DPKG_PATH=${DPKG_PATH}" >> $GITHUB_OUTPUT
- # build dpkg
- fakeroot dpkg-deb --build "${DPKG_DIR}" "${DPKG_PATH}"
- - name: "Artifact upload: tarball"
- uses: actions/upload-artifact@master
- with:
- name: ${{ steps.package.outputs.PKG_NAME }}
- path: ${{ steps.package.outputs.PKG_PATH }}
- - name: "Artifact upload: Debian package"
- uses: actions/upload-artifact@master
- if: steps.debian-package.outputs.DPKG_NAME
- with:
- name: ${{ steps.debian-package.outputs.DPKG_NAME }}
- path: ${{ steps.debian-package.outputs.DPKG_PATH }}
- - name: Check for release
- id: is-release
- shell: bash
- run: |
- unset IS_RELEASE ; if [[ $GITHUB_REF =~ ^refs/tags/v[0-9].* ]]; then IS_RELEASE='true' ; fi
- echo "IS_RELEASE=${IS_RELEASE}" >> $GITHUB_OUTPUT
- - name: Publish archives and packages
- uses: softprops/action-gh-release@v1
- if: steps.is-release.outputs.IS_RELEASE
- with:
- files: |
- ${{ steps.package.outputs.PKG_PATH }}
- ${{ steps.debian-package.outputs.DPKG_PATH }}
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|