From 5ec88adc97c0c07afb3bef17ec8734fe2daf6bc6 Mon Sep 17 00:00:00 2001 From: Jared Weakly Date: Tue, 1 Sep 2020 15:12:20 -0700 Subject: [PATCH] Add release workflow for GitHub Actions (#835) Add release workflow for github Co-authored-by: Aaron Tomb --- .github/ci.sh | 67 +++++++++++- .github/pr-labeler.yml | 5 + .github/release-drafter.yml | 32 ++++++ .github/workflows/build.yml | 170 +++++++++++++++++++++---------- .github/workflows/pr-labeler.yml | 12 +++ 5 files changed, 228 insertions(+), 58 deletions(-) create mode 100644 .github/pr-labeler.yml create mode 100644 .github/release-drafter.yml create mode 100644 .github/workflows/pr-labeler.yml diff --git a/.github/ci.sh b/.github/ci.sh index a1e48a281d..e4f196f14b 100755 --- a/.github/ci.sh +++ b/.github/ci.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -set -Eeuo pipefail +set -Eeuxo pipefail [[ "$RUNNER_OS" == 'Windows' ]] && IS_WIN=true || IS_WIN=false BIN=bin @@ -72,7 +72,12 @@ install_cvc4() { Windows) file="win64-opt.exe" ;; macOS) file="macos-opt" ;; esac - curl -o cvc4$EXT -sL "https://github.com/CVC4/CVC4/releases/download/$version/cvc4-$version-$file" + # Temporary workaround + if [[ "$RUNNER_OS" == "Linux" ]]; then + curl -o cvc4$EXT -sL "https://cvc4.cs.stanford.edu/downloads/builds/x86_64-linux-opt/unstable/cvc4-2020-08-18-x86_64-linux-opt" + else + curl -o cvc4$EXT -sL "https://github.com/CVC4/CVC4/releases/download/$version/cvc4-$version-$file" + fi $IS_WIN || chmod +x cvc4$EXT mv cvc4$EXT "$BIN/cvc4$EXT" } @@ -116,7 +121,11 @@ build() { if [[ "$ghc_ver" =~ 8.8.3|8.10.1 && $IS_WIN ]]; then JOBS=1; else JOBS=2; fi cabal v2-configure -j$JOBS --minimize-conflict-set tee -a cabal.project > /dev/null < cabal.project.ci - retry cabal v2-build "$@" saw jss + if ! retry cabal v2-build "$@" saw jss && [[ "$RUNNER_OS" == "macOS" ]]; then + echo "Working around a dylib issue on macos by removing the cache and trying again" + cabal v2-clean + retry cabal v2-build "$@" saw jss + fi } build_abc() { @@ -143,8 +152,6 @@ install_system_deps() { } test_dist() { - # To be replaced with a working implementation - # Copied from legacy CI setup_dist_bins find_java pushd intTests @@ -153,6 +160,30 @@ test_dist() { sh -c "! grep '' results.xml" } +build_cryptol() { + is_exe "dist/bin" "cryptol" && return + pushd deps/cryptol + .github/ci.sh build + popd +} + +bundle_files() { + mkdir -p dist dist/{bin,doc,examples,include,lib} + + cp deps/abcBridge/abc-build/copyright.txt dist/ABC_LICENSE + cp LICENSE README.md dist/ + $IS_WIN || chmod +x dist/bin/* + rm -f "dist/bin/jss" + + cp doc/extcore.md dist/doc + cp doc/tutorial/sawScriptTutorial.pdf dist/doc/tutorial.pdf + cp doc/manual/manual.pdf dist/doc/manual.pdf + cp -r doc/tutorial/code dist/doc + cp deps/jvm-verifier/support/galois.jar dist/lib + cp -r deps/cryptol/lib/* dist/lib + cp -r examples/* dist/examples +} + find_java() { pushd .github javac PropertiesTest.java @@ -163,6 +194,32 @@ find_java() { popd } +sign() { + gpg --batch --import <(echo "$SIGNING_KEY") + fingerprint="$(gpg --list-keys | grep galois -a1 | head -n1 | awk '{$1=$1};1')" + echo "$fingerprint:6" | gpg --import-ownertrust + gpg --yes --no-tty --batch --pinentry-mode loopback --default-key "$fingerprint" --detach-sign -o "$1".sig --passphrase-file <(echo "$SIGNING_PASSPHRASE") "$1" +} + +zip_dist() { + : "${VERSION?VERSION is required as an environment variable}" + name="${name:-"saw-$VERSION-$RUNNER_OS-x86_64"}" + mv dist "$name" + tar -czf "$name".tar.gz "$name" + sign "$name".tar.gz + [[ -f "$name".tar.gz.sig ]] && [[ -f "$name".tar.gz ]] +} + +output() { echo "::set-output name=$1::$2"; } +ver() { grep Version saw-script.cabal | awk '{print $2}'; } +set_version() { output saw-version "$(ver)"; } +set_files() { output changed-files "$(files_since "$1" "$2")"; } +files_since() { + changed_since="$(git log -1 --before="@{$2}")" + files="${changed_since:+"$(git diff-tree --no-commit-id --name-only -r "$1" | xargs)"}" + echo "$files" +} + COMMAND="$1" shift diff --git a/.github/pr-labeler.yml b/.github/pr-labeler.yml new file mode 100644 index 0000000000..06f7cdabc3 --- /dev/null +++ b/.github/pr-labeler.yml @@ -0,0 +1,5 @@ +feature: ["feature/*", "feat/*"] +enhancement: ["enhancement/*"] +fix: ["fix/*", "bugfix/*", "bug/*"] +breaking: ["breaking/*"] +solver: ["solver/*", "*z3*", "*cvc4*", "*yices*"] diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 0000000000..0ab92b9cf9 --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,32 @@ +name-template: "v$NEXT_PATCH_VERSION" +tag-template: "v$NEXT_PATCH_VERSION" +categories: + - title: "New Features" + labels: + - "feature" + - "enhancement" + - title: "Breaking Changes" + labels: + - "breaking" + - title: "Bug Fixes" + labels: + - "fix" + - "bugfix" + - "bug" + - title: "Solver Versions" + labels: + - "solver" +change-template: "- $TITLE @$AUTHOR (PR #$NUMBER)" + +replacers: + - search: '/Z3 (\d+)\.(\d+)\.(\d+)/ig' + replace: "[Z3 $1.$2.$3](https://github.com/Z3Prover/z3/releases/tag/z3-$1.$2.$3)" + - search: '/yices (\d+)\.(\d+)\.(\d+)/ig' + replace: "[Yices $1.$2.$3](https://yices.csl.sri.com/release-notes.html)" + - search: '/cvc(4?) (\d+)\.(\d+)\.(\d+)/ig' + replace: "[CVC4 $3.$4](https://github.com/CVC4/CVC4/releases/tag/$3.$4)" + +template: | + ## SAW-Script $NEXT_PATCH_VERSION + + $CHANGES diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 78b3b76474..e6ae2e0df2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,17 +1,52 @@ name: SAWScript on: push: - branches: [master] + branches: [master, "release-**"] pull_request: jobs: - build: + outputs: runs-on: ubuntu-latest + outputs: + changed: ${{ steps.outputs.outputs.changed-files }} + saw-version: ${{ steps.outputs.outputs.saw-version }} + name: ${{ steps.outputs.outputs.name }} + release: ${{ steps.env.outputs.release }} + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - id: env + if: | + startsWith(github.ref, 'refs/heads/release-') + || (github.event_name == 'pull_request' && startsWith(github.head_ref, 'actions/')) + run: .github/ci.sh output release 1 + - id: outputs + run: | + .github/ci.sh set_files ${{ github.sha }} + .github/ci.sh set_version + .github/ci.sh output name saw-$(.github/ci.sh ver) + + build: + runs-on: ${{ matrix.os }} + needs: [outputs] strategy: fail-fast: false matrix: - ghc: ["8.6.5", "8.8.3"] - name: SAWScript - GHC v${{ matrix.ghc }} - Ubuntu + os: [ubuntu-latest] + ghc: ["8.6.5", "8.8.4"] + continue-on-error: [false] + include: + - os: macos-latest + ghc: "8.6.5" + continue-on-error: true + - os: macos-latest + ghc: "8.8.4" + continue-on-error: true + name: SAWScript - GHC v${{ matrix.ghc }} - ${{ matrix.os }} + env: + RELEASE: ${{ needs.outputs.outputs.release }} + continue-on-error: ${{ matrix.continue-on-error }} steps: - uses: actions/checkout@v2 - run: | @@ -33,7 +68,6 @@ jobs: key: cabal-${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('**/cabal.GHC-*') }}-${{ github.sha }} restore-keys: | cabal-${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('**/cabal.GHC-*') }}- - cabal-${{ runner.os }}-${{ matrix.ghc }}- - shell: bash run: .github/ci.sh build_abc @@ -44,7 +78,7 @@ jobs: - shell: bash run: .github/ci.sh install_system_deps env: - Z3_VERSION: "4.8.7" + Z3_VERSION: "4.8.8" CVC4_VERSION: "4.1.8" YICES_VERSION: "2.6.2" @@ -56,17 +90,33 @@ jobs: - shell: bash id: test + continue-on-error: ${{ matrix.continue-on-error }} name: Integration Tests run: | mkdir -p ~/.stack echo "system-ghc: true" >> ~/.stack/config.yaml .github/ci.sh test_dist - + + - if: >- + env.RELEASE && matrix.ghc == '8.8.4' + run: | + .github/ci.sh build_cryptol + exe="$(cd deps/cryptol && cabal exec which cryptol)" + cp "$exe" "dist/bin" + + - if: >- + env.RELEASE && matrix.ghc == '8.8.4' + uses: actions/upload-artifact@v2 + with: + path: dist/bin + name: ${{ runner.os }}-bins + - name: Upload artifacts + if: "matrix.os == 'ubuntu-latest'" uses: actions/upload-artifact@v2 with: name: "saw-${{ runner.os }}-${{ matrix.ghc }}" - path: dist/bin/saw + path: "dist/bin/saw" - shell: bash if: "steps.test.outcome == 'failure'" @@ -87,13 +137,13 @@ jobs: - bike - tls - hmac-failure - ghc: ["8.6.5", "8.8.3"] + ghc: ["8.6.5", "8.8.4"] steps: - uses: actions/checkout@v2 - run: | mkdir -p s2nTests/bin - - name: Download previously-built SAW + - name: Download previously-built SAW uses: actions/download-artifact@v2 with: name: "saw-Linux-${{ matrix.ghc }}" @@ -106,65 +156,79 @@ jobs: chmod +x bin/saw make ${{ matrix.s2n-target }} - build-macos: - runs-on: macos-latest + bundle: + runs-on: ${{ matrix.os }} + if: needs.outputs.outputs.release strategy: fail-fast: false matrix: - ghc: ["8.6.5", "8.8.3"] - name: SAWScript - GHC v${{ matrix.ghc }} - MacOS + os: [ubuntu-latest, macos-latest] + ghc: ["8.8.4"] + needs: [outputs, build] + env: + VERSION: ${{ needs.outputs.outputs.saw-version }} + RELEASE: ${{ needs.outputs.outputs.release }} steps: - uses: actions/checkout@v2 - run: | git submodule update --init git -C deps/abcBridge submodule update --init - - uses: actions/setup-haskell@v1 - id: setup-haskell + - uses: actions/download-artifact@v2 with: - ghc-version: ${{ matrix.ghc }} - enable-stack: true - - - uses: actions/cache@v2 - name: Cache cabal store - with: - path: | - ${{ steps.setup-haskell.outputs.cabal-store }} - dist-newstyle - key: cabal-${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('**/cabal.GHC-*') }}-${{ github.sha }} - restore-keys: | - cabal-${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('**/cabal.GHC-*') }}- - cabal-${{ runner.os }}-${{ matrix.ghc }}- + path: dist/bin + name: ${{ runner.os }}-bins - shell: bash - run: .github/ci.sh build_abc - - - shell: bash - run: .github/ci.sh build + run: .github/ci.sh bundle_files - shell: bash - run: .github/ci.sh install_system_deps + continue-on-error: true # temporary to test release without setting up secrets env: - Z3_VERSION: "4.8.7" - CVC4_VERSION: "4.1.8" - YICES_VERSION: "2.6.2" + SIGNING_PASSPHRASE: ${{ secrets.SIGNING_PASSPHRASE }} + SIGNING_KEY: ${{ secrets.SIGNING_KEY }} + run: .github/ci.sh zip_dist - - uses: actions/setup-java@v1 + - uses: actions/upload-artifact@v2 with: - java-version: "8" - java-package: jdk - architecture: x64 + name: ${{ needs.outputs.outputs.name }}-${{ runner.os }}-x86_64 + path: "${{ needs.outputs.outputs.name }}-${{ runner.os }}-x86_64.tar.gz*" - - shell: bash - id: test - continue-on-error: true - name: Integration Tests - run: | - mkdir -p ~/.stack - echo "system-ghc: true" >> ~/.stack/config.yaml - .github/ci.sh test_dist + release: + needs: [outputs, bundle] + if: needs.outputs.outputs.release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: | + git submodule update --init + git -C deps/abcBridge submodule update --init - - shell: bash - if: "steps.test.outcome == 'failure'" - name: Warn if tests failed - run: echo "::error ::Test Suite Failed. Pipeline allowed to pass until tests are reliable." + - uses: release-drafter/release-drafter@v5 + id: release + with: + version: v${{ needs.outputs.outputs.saw-version }} + name: v${{ needs.outputs.outputs.saw-version }} + tag: v${{ needs.outputs.outputs.saw-version }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/download-artifact@v2 + with: + path: artifacts + - name: Upload artifacts to release + run: | + # workaround for draft-releaser being hard to test in CI + tag="v${VERSION}" + body="${body:-$tag}" + if ! hub release show "$tag"; then + hub release create -d -m "$body" "$tag" + fi + assets=() + find ./artifacts \( -name 'saw*.tar.gz*' -o -name '*.msi*' \) -type f -print0 | + while IFS= read -r -d '' a; do assets+=("-a" "$a"); done + hub release edit -d "${assets[@]}" -m "" "$tag" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ needs.outputs.outputs.saw-version }} + body: ${{ steps.release.outputs.body }} diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml new file mode 100644 index 0000000000..71267c6f1f --- /dev/null +++ b/.github/workflows/pr-labeler.yml @@ -0,0 +1,12 @@ +name: PR Labeler +on: + pull_request: + types: [opened] + +jobs: + pr-labeler: + runs-on: ubuntu-latest + steps: + - uses: TimonVS/pr-labeler-action@v3 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}