diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2f7896d --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +target/ diff --git a/.github/workflows/ci-hashcsv.yml b/.github/workflows/ci-hashcsv.yml new file mode 100644 index 0000000..4ef69ca --- /dev/null +++ b/.github/workflows/ci-hashcsv.yml @@ -0,0 +1,98 @@ +name: CI for hashcsv + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +on: + push: + # Run on the master branch. + branches: [main] + # Build anything with an appropriate release tag. + tags: ["hashcsv_*"] + paths: + - "hashcsv/**" + pull_request: + # Only run on pull requests against master. + branches: [main] + paths: + - "hashcsv/**" + +defaults: + run: + # Run all steps in this working directory. + working-directory: hashcsv + +jobs: + # We run this job first, to create any GitHub release that we might need. + # Creating a release can only be done once, so we need to split it out from + # other jobs. + create_release: + name: Create release (if needed) + runs-on: ubuntu-latest + outputs: + release_version: ${{ steps.extract_release_version.outputs.release_version }} + upload_url: ${{ steps.create_release.outputs.upload_url }} + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + - name: Extract release version + id: extract_release_version + run: | + release_version="$(echo '${{ github.ref }}' | sed 's,^.*/\([^/]*\),\1,; s,^hashcsv_,,; s,^v,,' )" + echo Release version: $release_version + echo "::set-output name=release_version::$release_version" + - name: Extract release body from CHANGELOG.md + id: extract_release_body + if: ${{ startsWith(github.ref, 'refs/tags/hashcsv_') }} + # Use `clparse` to parse `CHANGELOG.md` and extract release notes. + run: | + curl -sLO https://github.com/marcaddeo/clparse/releases/download/0.8.0/clparse-0.8.0-x86_64-unknown-linux-musl.tar.gz + tar xzf clparse*.tar.gz + sudo cp clparse /usr/local/bin + rm -rf clparse* + clparse -f json CHANGELOG.md | \ + jq ".releases[] | select(.version == \"${{ steps.extract_release_version.outputs.release_version }}\") | { title: \"\", description: \"\", releases: [.] }" | \ + clparse - | \ + tail -n +3 > RELEASE_BODY.md + - name: "Make release" + id: create_release + if: ${{ startsWith(github.ref, 'refs/tags/hashcsv_') }} + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: "hashcsv ${{ steps.extract_release_version.outputs.release_version }}" + body_path: hashcsv/RELEASE_BODY.md + + # We use a matrix to run our build on every supported platform. + build: + needs: + - create_release + + strategy: + matrix: + # The type of runner that the job will run on. + os: ["ubuntu-latest", "macos-latest"] + + runs-on: ${{ matrix.os }} + + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + - name: Test and build release + id: build_release + working-directory: . + run: | + export RELEASE_VERSION="${{ needs.create_release.outputs.release_version }}" + ./build-release hashcsv + echo "::set-output name=release_file::$(echo hashcsv-*.zip)" + - name: Upload Release Asset + if: ${{ startsWith(github.ref, 'refs/tags/hashcsv_') }} + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.create_release.outputs.upload_url }} + asset_path: ./${{ steps.build_release.outputs.release_file }} + asset_name: ${{ steps.build_release.outputs.release_file }} + asset_content_type: application/zip diff --git a/build-release b/build-release new file mode 100755 index 0000000..d35e881 --- /dev/null +++ b/build-release @@ -0,0 +1,54 @@ +#!/bin/bash +# +# Usage: ./build-release +# +# The latest version of this script is available at +# https://github.com/emk/rust-musl-builder/blob/master/examples/build-release +# +# Called by `.travis.yml` to build release binaries. We use +# ekidd/rust-musl-builder to make the Linux binaries so that we can run +# them unchanged on any distro, including tiny distros like Alpine (which +# is heavily used for Docker containers). Other platforms get regular +# binaries, which will generally be dynamically linked against libc. +# +# If you have a platform which supports static linking of libc, and this +# would be generally useful, please feel free to submit patches. + +set -euo pipefail + +# Command-line arguments. +PKG_NAME="$1" +BIN_NAME="$1" + +# This is either a tag, or possibly something like refs/heads/feature-branch-1. +# The important thing is that we remove all slashes. +VERSION="$RELEASE_VERSION" + +# Ask GCC for a triplet like "x86_64-linux-gnu". +TRIPLET="$(gcc -dumpmachine)" + +cd "$PKG_NAME" + +case `uname -s` in + Linux) + echo "Building static binaries using ekidd/rust-musl-builder" + # Build one directory up to make sure we can see our YAML. + docker build -t build-"$PKG_NAME"-image -f Dockerfile .. + docker run --name build-"$PKG_NAME" build-"$PKG_NAME"-image + mkdir -p dist + docker cp build-"$PKG_NAME":/home/rust/src/target/x86_64-unknown-linux-musl/release/"$BIN_NAME" dist/"$BIN_NAME" + docker rm build-"$PKG_NAME" + docker rmi build-"$PKG_NAME"-image + zip -j ../"$PKG_NAME"-v"$VERSION"-"$TRIPLET".zip dist/"$PKG_NAME" + rm -rf dist/ + ;; + Darwin) + echo "Building standard release binaries" + cargo build --release + zip -j ../"$PKG_NAME"-v"$VERSION"-"$TRIPLET"-osx.zip ../target/release/"$BIN_NAME" + ;; + *) + echo "Unknown platform" 2>&1 + exit 1 + ;; +esac \ No newline at end of file diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..11c9132 --- /dev/null +++ b/deny.toml @@ -0,0 +1,26 @@ +# Project policies. +# +# These policies can be enforced using `cargo deny check`. + +[licenses] +# Don't allow code with an unclear license. +unlicensed = "deny" + +# Don't allow "copylefted" licenses unless they're listed below. +copyleft = "deny" + +# Allow common non-restrictive licenses. +allow = ["MIT", "Apache-2.0", "BSD-3-Clause", "CC0-1.0"] + +# Also fine to allow. ISC is used for various DNS and crypto things, and it's a +# minimally restrictive open source license. +# +# "BSD-2-Clause", "ISC", "OpenSSL", "Zlib" + +# Many organizations ban AGPL-licensed code +# https://opensource.google/docs/using/agpl-policy/ +deny = ["AGPL-3.0"] + +[bans] +# Do we want to know about multiple versions of the same dependency? +multiple-versions = "allow" diff --git a/hashcsv/Dockerfile b/hashcsv/Dockerfile new file mode 100644 index 0000000..35e470b --- /dev/null +++ b/hashcsv/Dockerfile @@ -0,0 +1,14 @@ +# Dockerfile for building our Rust tools using GitHub Actions. +# +# Note that this actually gets "run" from the top-level directory and not the +# Rust subdirectory, so that we can see files in the top-level directories. + +FROM ekidd/rust-musl-builder + +# Add all the source code we'll need instead of trying to mount it, so that we +# don't have to mess around with UIDs. +ADD --chown=rust:rust . ./ + +WORKDIR /home/rust/src/hashcsv + +CMD cargo test && cargo clippy -- -D warnings && cargo deny check && cargo build --release