summaryrefslogtreecommitdiff
path: root/.github/workflows/coverity.yml
blob: c6d67e052631d0a5cc928d02d405d7dbb117c399 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
name: Coverity

# Coverity Scan gives relatively low-quality reports and has strict
# rate limits, so we only run it on the main branch on a schedule.
on:
  schedule:
    - cron: '31 3 * * 1'  # Monday at 3h31 UTC
  workflow_dispatch:

jobs:
  Coverity:
    runs-on: ubuntu-latest

    env:
      CVT_PROJECT: besser82/libxcrypt

    # Coverity doesn't have official Github Actions integration yet.
    # The steps below were kitbashed together from the contents of
    # https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh
    # plus some notions from
    # https://github.com/ruby/actions-coverity-scan/blob/master/.github/workflows/coverity-scan.yml
    steps:
    - name: Check for authorization
      env:
        CVT_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
      run: |
        if [ -z "$CVT_TOKEN" ]; then
          printf '\033[33;1mCoverity Scan token not available.\033[0m\n'
          exit 1
        fi
        AUTH_RES=$(curl -s --form project="$CVT_PROJECT" \
                           --form token="$CVT_TOKEN" \
                           https://scan.coverity.com/api/upload_permitted)
        if [ "$AUTH_RES" = "Access denied" ]; then
          printf '\033[33;1mCoverity Scan API access denied.\033[0m\n'
          printf 'Check project name and access token.\n'
          exit 1
        else
          AUTH=$(printf '%s' "$AUTH_RES" | ruby -e "
            require 'rubygems'
            require 'json'
            puts JSON[STDIN.read]['upload_permitted']
          ")
          if [ "$AUTH" = "true" ]; then
            echo ok
            exit 0
          else
            WHEN=$(printf '%s' "$AUTH_RES" | ruby -e "
              require 'rubygems'
              require 'json'
              puts JSON[STDIN.read]['next_upload_permitted_at']
            ")
            printf '\033[33;1mCoverity Scan access blocked until %s.\033[0m\n' \
              "$WHEN"
            exit 1
          fi
        fi

    - name: Checkout repository
      uses: actions/checkout@v2

    - name: Download Coverity Build Tool
      env:
        CVT_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
      run: |
        echo Downloading Coverity tools...
        # Put the tools in the parent directory so the build can't
        # clobber them by accident.
        cd ..
        curl --no-progress-meter -o cov-analysis-linux64.tar.gz \
             --form token="$CVT_TOKEN" \
             --form project="$CVT_PROJECT" \
             https://scan.coverity.com/download/cxx/linux64
        echo Extracting...
        mkdir cov-analysis-linux64
        tar xzf cov-analysis-linux64.tar.gz --strip 1 -C cov-analysis-linux64
        echo done.
        if [ -f cov-analysis-linux64/VERSION ]; then
          echo ::group::Coverity tool versions
          echo + cat cov-analysis-linux64/VERSION
          echo
          cat cov-analysis-linux64/VERSION
          echo ::endgroup::
        fi

    - name: Versions of build tools
      id: build-tools
      run: ./build-aux/ci/ci-log-dependency-versions

    - name: Get nprocs
      run: echo "NPROCS=$((`nproc --all 2>/dev/null || sysctl -n hw.ncpu` * 2))" | tee $GITHUB_ENV

    - name: Cache bootstrap
      id: cache
      uses: actions/cache@v2
      with:
        path: |
          INSTALL
          Makefile.in
          aclocal.m4
          config.h.in
          configure
          autom4te.cache/**
          build-aux/m4/libtool.m4
          build-aux/m4/ltoptions.m4
          build-aux/m4/ltsugar.m4
          build-aux/m4/ltversion.m4
          build-aux/m4/lt~obsolete.m4
          build-aux/m4-autogen/**
        key: autoreconf-${{ steps.build-tools.outputs.autotools-ver }}-${{ hashFiles('autogen.sh', 'configure.ac', 'Makefile.am', 'build-aux/m4/*.m4', 'build-aux/m4-autogen/**') }}

    - name: Bootstrap
      if: steps.cache.outputs.cache-hit != 'true'
      run: ./autogen.sh

    - name: Configure
      run: ./configure --disable-werror --enable-obsolete-api --enable-hashes=all

    - name: Prepare build script
      run: |
        echo '#! /bin/sh' > cov_make.sh
        echo "make -j${{ env.NPROCS }} all" >> cov_make.sh
        echo "make -j${{ env.NPROCS }} test-programs" >> cov_make.sh
        chmod +x cov_make.sh

    - name: Build
      run: |
        export PATH=$(cd .. && pwd)/cov-analysis-linux64/bin:$PATH
        cov-build --dir cov-int ./cov_make.sh
        cov-import-scm --dir cov-int --scm git --log cov-int/scm_log.txt

    - name: Upload analysis results
      env:
        CVT_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
        CVT_EMAIL: ${{ secrets.COVERITY_SCAN_NOTIFICATION_EMAIL }}
      run: |
        tar czvf cov-int.tar.gz cov-int
        printf 'Uploading Coverity Scan Analysis results...\n'
        response=$(curl -s --write-out '\n%{http_code}\n' \
          --form project="$CVT_PROJECT" \
          --form token="$CVT_TOKEN" \
          --form email="$CVT_EMAIL" \
          --form file=@cov-int.tar.gz \
          --form version="${GITHUB_REF}" \
          --form description="${GITHUB_SHA}" \
          https://scan.coverity.com/builds)
        status_code=$(echo "$response" | sed -n '$p')
        if [ "$status_code" = "200" ] || [ "$status_code" = "201" ] ; then
          printf 'Upload complete.\n'
          exit 0
        else
          TEXT=$(echo "$response" | sed '$d')
          printf '\033[33;1mCoverity Scan upload failed:\033[0m\n%s.\n' "$TEXT"
          exit 1
        fi

    - name: Detailed error logs
      if: failure()
      run: ./build-aux/ci/ci-log-logfiles