summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Peter <mail@david-peter.de>2021-11-14 09:35:02 +0100
committerDavid Peter <sharkdp@users.noreply.github.com>2021-11-14 09:51:41 +0100
commitf146a3f5ca24ad2c66147b5ec05dd1b37480159b (patch)
treebcb2022bb8db18bb39ddc734ac2ec7ede17a5c0a
parentfc383723b79c9f0d9c142ca27669093188c2c26c (diff)
Migrate to GitHub actions
-rw-r--r--.github/workflows/CICD.yml327
-rw-r--r--.travis.yml80
-rwxr-xr-xci/before_deploy.bash108
3 files changed, 327 insertions, 188 deletions
diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml
new file mode 100644
index 0000000..922be50
--- /dev/null
+++ b/.github/workflows/CICD.yml
@@ -0,0 +1,327 @@
+name: CICD
+
+env:
+ MIN_SUPPORTED_RUST_VERSION: "1.50.0"
+ CICD_INTERMEDIATES_DIR: "_cicd-intermediates"
+
+on:
+ workflow_dispatch:
+ pull_request:
+ push:
+ branches:
+ - master
+ tags:
+ - '*'
+
+jobs:
+ min_version:
+ name: Minimum supported rust version
+ runs-on: ubuntu-20.04
+ steps:
+ - name: Checkout source code
+ uses: actions/checkout@v2
+
+ - name: Install rust toolchain (v${{ env.MIN_SUPPORTED_RUST_VERSION }})
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: ${{ env.MIN_SUPPORTED_RUST_VERSION }}
+ default: true
+ profile: minimal # minimal component installation (ie, no documentation)
+ components: clippy, rustfmt
+ - name: Ensure `cargo fmt` has been run
+ uses: actions-rs/cargo@v1
+ with:
+ command: fmt
+ args: -- --check
+ - name: Run clippy (on minimum supported rust version to prevent warnings we can't fix)
+ uses: actions-rs/cargo@v1
+ with:
+ command: clippy
+ args: --locked --all-targets --all-features
+ - name: Run tests
+ uses: actions-rs/cargo@v1
+ with:
+ command: test
+ args: --locked
+
+ build:
+ name: ${{ matrix.job.os }} (${{ matrix.job.target }})
+ runs-on: ${{ matrix.job.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ job:
+ - { os: ubuntu-20.04, target: arm-unknown-linux-gnueabihf , use-cross: true }
+ - { os: ubuntu-20.04, target: arm-unknown-linux-musleabihf, use-cross: true }
+ - { os: ubuntu-20.04, target: aarch64-unknown-linux-gnu , use-cross: true }
+ - { os: ubuntu-20.04, target: i686-unknown-linux-gnu , use-cross: true }
+ - { os: ubuntu-20.04, target: i686-unknown-linux-musl , use-cross: true }
+ - { os: ubuntu-20.04, target: x86_64-unknown-linux-gnu }
+ - { os: ubuntu-20.04, target: x86_64-unknown-linux-musl , use-cross: true }
+ - { os: macos-10.15 , target: x86_64-apple-darwin }
+ # - { os: windows-2019, target: i686-pc-windows-gnu } ## disabled; error: linker `i686-w64-mingw32-gcc` not found
+ - { os: windows-2019, target: i686-pc-windows-msvc }
+ - { os: windows-2019, target: x86_64-pc-windows-gnu }
+ - { os: windows-2019, target: x86_64-pc-windows-msvc }
+ steps:
+ - name: Checkout source code
+ uses: actions/checkout@v2
+
+ - 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: Extract crate information
+ shell: bash
+ run: |
+ echo "PROJECT_NAME=diskus" >> $GITHUB_ENV
+ echo "PROJECT_VERSION=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -n1)" >> $GITHUB_ENV
+ echo "PROJECT_MAINTAINER=$(sed -n 's/^authors = \["\(.*\)"\]/\1/p' Cargo.toml)" >> $GITHUB_ENV
+ echo "PROJECT_HOMEPAGE=$(sed -n 's/^homepage = "\(.*\)"/\1/p' Cargo.toml)" >> $GITHUB_ENV
+
+ - name: Install Rust toolchain
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: stable
+ target: ${{ matrix.job.target }}
+ override: true
+ profile: minimal # minimal component installation (ie, no documentation)
+
+ - 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
+ uses: actions-rs/cargo@v1
+ with:
+ use-cross: ${{ matrix.job.use-cross }}
+ command: build
+ args: --locked --release --target=${{ matrix.job.target }}
+
+ - name: Strip debug information from executable
+ id: strip
+ shell: bash
+ run: |
+ # Figure out suffix of binary
+ EXE_suffix=""
+ case ${{ matrix.job.target }} in
+ *-pc-windows-*) EXE_suffix=".exe" ;;
+ esac;
+
+ # Figure out what strip tool to use if any
+ STRIP="strip"
+ case ${{ matrix.job.target }} in
+ arm-unknown-linux-*) STRIP="arm-linux-gnueabihf-strip" ;;
+ aarch64-unknown-linux-gnu) STRIP="aarch64-linux-gnu-strip" ;;
+ *-pc-windows-msvc) STRIP="" ;;
+ esac;
+
+ # Setup paths
+ BIN_DIR="${{ env.CICD_INTERMEDIATES_DIR }}/stripped-release-bin/"
+ mkdir -p "${BIN_DIR}"
+ BIN_NAME="${{ env.PROJECT_NAME }}${EXE_suffix}"
+ BIN_PATH="${BIN_DIR}/${BIN_NAME}"
+
+ # Copy the release build binary to the result location
+ cp "target/${{ matrix.job.target }}/release/${BIN_NAME}" "${BIN_DIR}"
+
+ # Also strip if possible
+ if [ -n "${STRIP}" ]; then
+ "${STRIP}" "${BIN_PATH}"
+ fi
+
+ # Let subsequent steps know where to find the (stripped) bin
+ echo ::set-output name=BIN_PATH::${BIN_PATH}
+ echo ::set-output name=BIN_NAME::${BIN_NAME}
+
+ - 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 ${PROJECT_NAME}" ;; esac;
+ echo ::set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS}
+
+ - name: Run tests
+ uses: actions-rs/cargo@v1
+ with:
+ use-cross: ${{ matrix.job.use-cross }}
+ command: test
+ args: --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=${PROJECT_NAME}-v${PROJECT_VERSION}-${{ matrix.job.target }}
+ PKG_NAME=${PKG_BASENAME}${PKG_suffix}
+ echo ::set-output name=PKG_NAME::${PKG_NAME}
+
+ PKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/package"
+ ARCHIVE_DIR="${PKG_STAGING}/${PKG_BASENAME}/"
+ mkdir -p "${ARCHIVE_DIR}"
+
+ # Binary
+ cp "${{ steps.strip.outputs.BIN_PATH }}" "$ARCHIVE_DIR"
+
+ # Man page
+ cp 'doc/${{ env.PROJECT_NAME }}.1' "$ARCHIVE_DIR"
+
+ # README, LICENSE and CHANGELOG files
+ cp "README.md" "LICENSE-MIT" "LICENSE-APACHE" "CHANGELOG.md" "$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 ::set-output name=PKG_PATH::"${PKG_STAGING}/${PKG_NAME}"
+
+ - name: Create Debian package
+ id: debian-package
+ shell: bash
+ if: startsWith(matrix.job.os, 'ubuntu')
+ run: |
+ COPYRIGHT_YEARS="2018 - "$(date "+%Y")
+ DPKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/debian-package"
+ DPKG_DIR="${DPKG_STAGING}/dpkg"
+ mkdir -p "${DPKG_DIR}"
+
+ DPKG_BASENAME=${PROJECT_NAME}
+ DPKG_CONFLICTS=${PROJECT_NAME}-musl
+ case ${{ matrix.job.target }} in *-musl) DPKG_BASENAME=${PROJECT_NAME}-musl ; DPKG_CONFLICTS=${PROJECT_NAME} ;; esac;
+ DPKG_VERSION=${PROJECT_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 ::set-output name=DPKG_NAME::${DPKG_NAME}
+
+ # Binary
+ install -Dm755 "${{ steps.strip.outputs.BIN_PATH }}" "${DPKG_DIR}/usr/bin/${{ steps.strip.outputs.BIN_NAME }}"
+
+ # Man page
+ install -Dm644 'doc/${{ env.PROJECT_NAME }}.1' "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1"
+ gzip -n --best "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1"
+
+ # 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"
+ install -Dm644 "CHANGELOG.md" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/changelog"
+ gzip -n --best "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/changelog"
+
+ cat > "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/copyright" <<EOF
+ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+ Upstream-Name: ${{ env.PROJECT_NAME }}
+ Source: ${{ env.PROJECT_HOMEPAGE }}
+
+ Files: *
+ Copyright: ${{ env.PROJECT_MAINTAINER }}
+ Copyright: $COPYRIGHT_YEARS ${{ env.PROJECT_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: ${{ env.PROJECT_MAINTAINER }}
+ Homepage: ${{ env.PROJECT_HOMEPAGE }}
+ Architecture: ${DPKG_ARCH}
+ Provides: ${{ env.PROJECT_NAME }}
+ Conflicts: ${DPKG_CONFLICTS}
+ Description: Minimal and fast alternative to 'du -sh'.
+ EOF
+
+ DPKG_PATH="${DPKG_STAGING}/${DPKG_NAME}"
+ echo ::set-output name=DPKG_PATH::${DPKG_PATH}
+
+ # 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 ::set-output name=IS_RELEASE::${IS_RELEASE}
+
+ - 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 }}
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 63586f6..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,80 +0,0 @@
-language: rust
-cache: cargo
-matrix:
- include:
- # Stable channel.
- - os: linux
- rust: stable
- env: TARGET=x86_64-unknown-linux-gnu
- - os: linux
- rust: stable
- env: TARGET=x86_64-unknown-linux-musl
- - os: osx
- rust: stable
- env: TARGET=x86_64-apple-darwin
- - os: windows
- rust: stable
- env: TARGET=x86_64-pc-windows-msvc
-
- # Minimum Rust supported channel.
- - os: linux
- rust: 1.34.0
- env: TARGET=x86_64-unknown-linux-gnu
-
-
-addons:
- apt:
- packages:
- # needed to build deb packages
- - fakeroot
-
-env:
- global:
- # Default target on travis-ci.
- # Used as conditional check in the install stage
- - HOST=x86_64-unknown-linux-gnu
- # Used on the deployment script
- - PROJECT_NAME=diskus
-
-install:
- # prevent target re-add error from rustup
- - if [[ $TRAVIS_OS_NAME = linux && $HOST != $TARGET ]]; then rustup target add $TARGET; fi
-
-script:
- # Incorporate TARGET env var to the build and test process
- - cargo build --target $TARGET --verbose
- - cargo test --target $TARGET --verbose
- - cargo run
-
-before_deploy:
- - bash ci/before_deploy.bash
-
-deploy:
- provider: releases
- # NOTE updating the `api_key.secure`
- # - go to: https://github.com/settings/tokens/new
- # - generate new token using `public_repo` scope
- # - encrypt it using: `travis encrypt API_KEY_HERE`
- # - paste the output below
- api_key:
- secure: "eibfoNCoqJEXfOpaCrQHMPSpmmThPitZB0nTWp0B8F5n29XmiMVpRDFz6LkbWt9xosyhlDK0coes+lJ/b4JIV7JVOJ3jhXNynhElVp0nHvhSN3CCzBk65nJjRPCsmyVjKn/Nj7fIwQJJrCxiAOdq+0DZPpl+Ix5GArXYJ3CLxLE/gwnHOkTqgrG612YmQQP68Cu9MsasRJt9SPxxGUsnNdPyfezxTQwu0BwWHzL/J3fa/e2HWFuFx6tD69fqF6k3Yt3i2fXasX1wDGvKLz36ttjsgqGYTAHf5nUFkz4l0O/bSRcrsqxxRjS1UGGa2PFvpPQE6OiV9szJSPEd2wP9OedbcTKybmmYpOHXJV4KpoLsY88aBtuLfMHkE6TfK67Otvp1lw59XHXHB4W3L1fEgB1TP3LW3AjAXlP9buE/a0pxrc85Z9oHasD3s4SgH5mMiaAXwZEiR5GWM1TWc3+hPOQH4K/TCZfM5qkFLcDMBtxfkanx6Yts4EKojA6T0O8Gh27AAYW/0mEdOjNnoOY6A8jengluZBrAxdW+hekgVMMHXFtXG2JohAQpEgYYKX1TOybslipeMzXDysdmouxjRK3Bi4ccjVDkSjfg020x8JVQCg7UQBfu6V2m/8Y0dfmczVmDOJkcwFnPaK/OQ9uub/bwLaa41G0Fjcxc+/FVb8c="
- # for uploading multiple files
- file_glob: true
- # NOTE explanation on each env variable
- # - PROJECT_NAME: name of the project, set on the `env.global` above
- # - TRAVIS_TAG: tag name that the build is being deployed for, usually the version number
- # - TARGET: target triple of the build
- file:
- - $PROJECT_NAME-$TRAVIS_TAG-$TARGET.*
- - $PROJECT_NAME*.deb
- # don't delete artifacts from previous stage
- skip_cleanup: true
- on:
- # deploy only if we push a tag
- tags: true
- # deploy only on stable channel that has TARGET env variable sets
- condition: $TRAVIS_RUST_VERSION = stable && $TARGET != ""
-
-notifications:
- email:
- on_success: never
diff --git a/ci/before_deploy.bash b/ci/before_deploy.bash
deleted file mode 100755
index 6165827..0000000
--- a/ci/before_deploy.bash
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/usr/bin/env bash
-# Building and packaging for release
-
-set -ex
-
-build() {
- cargo build --target "$TARGET" --release --verbose
-}
-
-pack() {
- local tempdir
- local out_dir
- local package_name
-
- tempdir=$(mktemp -d 2>/dev/null || mktemp -d -t tmp)
- out_dir=$(pwd)
- package_name="$PROJECT_NAME-$TRAVIS_TAG-$TARGET"
-
- # create a "staging" directory
- mkdir "$tempdir/$package_name"
-
- # copying the main binary
- cp "target/$TARGET/release/$PROJECT_NAME" "$tempdir/$package_name/"
- strip "$tempdir/$package_name/$PROJECT_NAME"
-
- # manpage, readme and license
- cp "doc/$PROJECT_NAME.1" "$tempdir/$package_name"
- cp README.md "$tempdir/$package_name"
- cp LICENSE-MIT "$tempdir/$package_name"
- cp LICENSE-APACHE "$tempdir/$package_name"
-
- # archiving
- pushd "$tempdir"
- tar czf "$out_dir/$package_name.tar.gz" "$package_name"/*
- popd
- rm -r "$tempdir"
-}
-
-make_deb() {
- local tempdir
- local architecture
- local version
- local dpkgname
- local conflictname
-
- case $TARGET in
- x86_64*)
- architecture=amd64
- ;;
- i686*)
- architecture=i386
- ;;
- *)
- echo "ERROR: unknown target" >&2
- return 1
- ;;
- esac
- version=${TRAVIS_TAG#v}
- if [[ $TARGET = *musl* ]]; then
- dpkgname=$PROJECT_NAME-musl
- conflictname=$PROJECT_NAME
- else
- dpkgname=$PROJECT_NAME
- conflictname=$PROJECT_NAME-musl
- fi
-
- tempdir=$(mktemp -d 2>/dev/null || mktemp -d -t tmp)
-
- # copy the main binary
- install -Dm755 "target/$TARGET/release/$PROJECT_NAME" "$tempdir/usr/bin/$PROJECT_NAME"
- strip "$tempdir/usr/bin/$PROJECT_NAME"
-
- # manpage
- install -Dm644 "doc/$PROJECT_NAME.1" "$tempdir/usr/share/man/man1/$PROJECT_NAME.1"
- gzip --best "$tempdir/usr/share/man/man1/$PROJECT_NAME.1"
-
- # readme and license
- install -Dm644 README.md "$tempdir/usr/share/doc/$PROJECT_NAME/README.md"
- install -Dm644 LICENSE-MIT "$tempdir/usr/share/doc/$PROJECT_NAME/LICENSE-MIT"
- install -Dm644 LICENSE-APACHE "$tempdir/usr/share/doc/$PROJECT_NAME/LICENSE-APACHE"
-
- # Control file
- mkdir "$tempdir/DEBIAN"
- cat > "$tempdir/DEBIAN/control" <<EOF
-Package: $dpkgname
-Version: $version
-Section: utils
-Priority: optional
-Maintainer: David Peter <mail@david-peter.de>
-Architecture: $architecture
-Provides: $PROJECT_NAME
-Conflicts: $conflictname
-Description: A minimal, fast alternative to 'du -sh'.
-EOF
-
- fakeroot dpkg-deb --build "$tempdir" "${dpkgname}_${version}_${architecture}.deb"
-}
-
-
-main() {
- build
- pack
- if [[ $TARGET = *linux* ]]; then
- make_deb
- fi
-}
-
-main