소스 검색

check for api breakage in ci and prepare to test with thread sanitizer (#102)

motivation: better ci testing

changes:
* add api breakage script to test api breakage in ci
* add "shell" utility docker-compose task to run api breakage script
* change test task to treat warning as errors
* prepare to test with thread sanitizer in 5.1
tomer doron 5 년 전
부모
커밋
f0f77b00c4
5개의 변경된 파일153개의 추가작업 그리고 3개의 파일을 삭제
  1. 1 1
      docker/Dockerfile
  2. 3 0
      docker/docker-compose.1804.50.yaml
  3. 5 0
      docker/docker-compose.1804.51.yaml
  4. 8 2
      docker/docker-compose.yaml
  5. 136 0
      scripts/check_no_api_breakages.sh

+ 1 - 1
docker/Dockerfile

@@ -13,7 +13,7 @@ ENV LANGUAGE en_US.UTF-8
 
 # dependencies
 RUN apt-get update && apt-get install -y wget
-RUN apt-get update && apt-get install -y lsof dnsutils netcat-openbsd net-tools # used by integration tests
+RUN apt-get update && apt-get install -y lsof dnsutils netcat-openbsd net-tools curl jq # used by integration tests
 
 # ruby and jazzy for docs generation
 RUN apt-get update && apt-get install -y ruby ruby-dev libsqlite3-dev

+ 3 - 0
docker/docker-compose.1804.50.yaml

@@ -11,3 +11,6 @@ services:
 
   test:
     image: swift-log:18.04-5.0
+
+  shell:
+    image: swift-log:18.04-5.0

+ 5 - 0
docker/docker-compose.1804.51.yaml

@@ -11,3 +11,8 @@ services:
 
   test:
     image: swift-log:18.04-5.1
+    environment: []
+      #- SANITIZER_ARG=--sanitize=thread
+
+  shell:
+    image: swift-log:18.04-5.1

+ 8 - 2
docker/docker-compose.yaml

@@ -21,8 +21,14 @@ services:
 
   sanity:
     <<: *common
-    command: /bin/bash -cl "./scripts/sanity.sh"
+    command: /bin/bash -xcl "./scripts/sanity.sh"
 
   test:
     <<: *common
-    command: /bin/bash -cl "swift test"
+    command: /bin/bash -xcl "swift test -Xswiftc -warnings-as-errors $${SANITIZER_ARG-}"
+
+  # util
+
+  shell:
+    <<: *common
+    entrypoint: /bin/bash

+ 136 - 0
scripts/check_no_api_breakages.sh

@@ -0,0 +1,136 @@
+#!/bin/bash
+##===----------------------------------------------------------------------===##
+##
+## This source file is part of the Swift Logging API open source project
+##
+## Copyright (c) 2019 Apple Inc. and the Swift Logging API project authors
+## Licensed under Apache License v2.0
+##
+## See LICENSE.txt for license information
+## See CONTRIBUTORS.txt for the list of Swift Logging API project authors
+##
+## SPDX-License-Identifier: Apache-2.0
+##
+##===----------------------------------------------------------------------===##
+
+##===----------------------------------------------------------------------===##
+##
+## This source file is part of the SwiftNIO open source project
+##
+## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors
+## Licensed under Apache License v2.0
+##
+## See LICENSE.txt for license information
+## See CONTRIBUTORS.txt for the list of SwiftNIO project authors
+##
+## SPDX-License-Identifier: Apache-2.0
+##
+##===----------------------------------------------------------------------===##
+
+set -eu
+
+# repodir
+function all_modules() {
+    local repodir="$1"
+    (
+    set -eu
+    cd "$repodir"
+    swift package dump-package | jq '.products |
+                                     map(select(.type | has("library") )) |
+                                     map(.name) | .[]' | tr -d '"'
+    )
+}
+
+# repodir tag output
+function build_and_do() {
+    local repodir=$1
+    local tag=$2
+    local output=$3
+
+    (
+    cd "$repodir"
+    git checkout -q "$tag"
+    swift build
+    while read -r module; do
+        swift api-digester -sdk "$sdk" -dump-sdk -module "$module" \
+            -o "$output/$module.json" -I "$repodir/.build/debug"
+    done < <(all_modules "$repodir")
+    )
+}
+
+function usage() {
+    echo >&2 "Usage: $0 REPO-GITHUB-URL NEW-VERSION OLD-VERSIONS..."
+    echo >&2
+    echo >&2 "This script requires a Swift 5.1+ toolchain."
+    echo >&2
+    echo >&2 "Examples:"
+    echo >&2
+    echo >&2 "Check between master and tag 2.1.1 of swift-nio:"
+    echo >&2 "  $0 https://github.com/apple/swift-nio master 2.1.1"
+    echo >&2
+    echo >&2 "Check between HEAD and commit 64cf63d7 using the provided toolchain:"
+    echo >&2 "  xcrun --toolchain org.swift.5120190702a $0 ../some-local-repo HEAD 64cf63d7"
+}
+
+if [[ $# -lt 3 ]]; then
+    usage
+    exit 1
+fi
+
+sdk=/
+if [[ "$(uname -s)" == Darwin ]]; then
+    sdk=$(xcrun --show-sdk-path)
+fi
+
+hash jq 2> /dev/null || { echo >&2 "ERROR: jq must be installed"; exit 1; }
+tmpdir=$(mktemp -d /tmp/.check-api_XXXXXX)
+repo_url=$1
+new_tag=$2
+shift 2
+
+repodir="$tmpdir/repo"
+git clone "$repo_url" "$repodir"
+git -C "$repodir" fetch -q origin '+refs/pull/*:refs/remotes/origin/pr/*'
+errors=0
+
+for old_tag in "$@"; do
+    mkdir "$tmpdir/api-old"
+    mkdir "$tmpdir/api-new"
+
+    echo "Checking public API breakages from $old_tag to $new_tag"
+
+    build_and_do "$repodir" "$new_tag" "$tmpdir/api-new/"
+    build_and_do "$repodir" "$old_tag" "$tmpdir/api-old/"
+
+    for f in "$tmpdir/api-new"/*; do
+        f=$(basename "$f")
+        report="$tmpdir/$f.report"
+        if [[ ! -f "$tmpdir/api-old/$f" ]]; then
+            echo "NOTICE: NEW MODULE $f"
+            continue
+        fi
+
+        echo -n "Checking $f... "
+        swift api-digester -sdk "$sdk" -diagnose-sdk \
+            --input-paths "$tmpdir/api-old/$f" -input-paths "$tmpdir/api-new/$f" 2>&1 \
+            > "$report" 2>&1
+
+        if ! shasum "$report" | grep -q cefc4ee5bb7bcdb7cb5a7747efa178dab3c794d5; then
+            echo ERROR
+            echo >&2 "=============================="
+            echo >&2 "ERROR: public API change in $f"
+            echo >&2 "=============================="
+            cat >&2 "$report"
+            errors=$(( errors + 1 ))
+        else
+            echo OK
+        fi
+    done
+    rm -rf "$tmpdir/api-new" "$tmpdir/api-old"
+done
+
+if [[ "$errors" == 0 ]]; then
+    echo "OK, all seems good"
+fi
+echo done
+exit "$errors"