aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/.github/workflows/ci.yml
blob: c977b1d90b1b64aa1e392816ae1a79847e91da6e (plain) (blame)
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
name: CI

on:
  push:
  pull_request:
  workflow_dispatch:

env:
  DEPS: libgit2-dev libjson-c-dev libsodium-dev libsqlite3-dev python3-pytest

jobs:
  lint:
    runs-on: ubuntu-latest
    name: Linting
    continue-on-error: ${{ github.ref != 'refs/heads/master' }}
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Run clang-format
        uses: egor-tensin/clang-format@v1

  build:
    strategy:
      matrix:
        compiler: [gcc, clang]
        configuration: [Debug, Release]
    runs-on: ubuntu-latest
    name: 'Build: ${{ matrix.compiler }} / ${{ matrix.configuration }}'
    env:
      COMPILER: '${{ matrix.compiler }}'
      CONFIGURATION: '${{ matrix.configuration }}'
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          # Unpin when this is fixed: https://github.com/python/cpython/issues/111615
          python-version: '3.11'
          cache: pip
          cache-dependency-path: ./test/requirements.txt
      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends $DEPS valgrind
          pip install -q -r ./test/requirements.txt
      - name: Build
        run: make install
      - name: Upload binaries
        uses: actions/upload-artifact@v3
        with:
          name: 'cimple-${{ matrix.compiler }}-${{ matrix.configuration }}'
          path: './build/install/'
          if-no-files-found: error
      - name: Run tests
        run: make test/report
      - name: Upload test report
        uses: actions/upload-artifact@v3
        with:
          name: 'test-report-${{ matrix.compiler }}-${{ matrix.configuration }}'
          path: './build/test_report/'
          if-no-files-found: error
        if: always()
      - name: Run Valgrind tests
        run: make test/valgrind

  coverage:
    runs-on: ubuntu-latest
    name: 'Code coverage'
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends $DEPS gcovr
      - name: Generate coverage report
        run: make coverage
      - name: Upload coverage report
        uses: actions/upload-artifact@v3
        with:
          name: coverage
          path: ./build/coverage/
          if-no-files-found: error

  flame_graphs:
    runs-on: ubuntu-latest
    name: 'Flame graphs'
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends $DEPS
      - name: Install FlameGraph
        run: |
          git clone --depth 1 https://github.com/brendangregg/FlameGraph.git ~/FlameGraph
          echo ~/FlameGraph >> "$GITHUB_PATH"
      - name: Enable profiling
        run: |
          echo -1 | sudo tee /proc/sys/kernel/perf_event_paranoid
      - name: Build
        run: make install
      - name: Make flame graphs
        run: |
          # sudo is used to resolve kernel symbols. Plus, it would be required
          # if we didn't fix perf_event_paranoid. PATH needs to be preserved
          # for FlameGraph.
          sudo --preserve-env=PATH make flame_graphs
      - name: Upload flame graphs
        uses: actions/upload-artifact@v3
        with:
          name: flame_graphs
          path: ./build/flame_graphs/
          if-no-files-found: error

  publish_reports:
    needs: [build, coverage, flame_graphs]
    runs-on: ubuntu-latest
    name: 'Publish: reports'
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Download test report - Clang/Debug
        uses: actions/download-artifact@v3
        with:
          name: test-report-clang-Debug
          path: /tmp/reports/test_report_clang_debug/
      - name: Download test report - Clang/Release
        uses: actions/download-artifact@v3
        with:
          name: test-report-clang-Release
          path: /tmp/reports/test_report_clang_release/
      - name: Download coverage report
        uses: actions/download-artifact@v3
        with:
          name: coverage
          path: /tmp/reports/coverage
      - name: Download flame graphs
        uses: actions/download-artifact@v3
        with:
          name: flame_graphs
          path: /tmp/reports/flame_graphs
      - name: Publish to GitHub Pages
        uses: JamesIves/github-pages-deploy-action@v4
        with:
          folder: /tmp/reports/
          single-commit: true
        if: github.ref == 'refs/heads/master'

  publish_docker:
    needs: [lint, build]
    runs-on: ubuntu-latest
    name: 'Publish: Docker Hub'
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2
      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: '${{ secrets.DOCKERHUB_USERNAME }}'
          password: '${{ secrets.DOCKERHUB_TOKEN }}'
      - id: platforms
        name: Which platforms?
        # Building for ARM for every commit not in master is too time-consuming.
        run: |
          if [ '${{ github.ref }}' = 'refs/heads/master' ]; then
              echo 'platforms=amd64,armhf,arm64' >> "$GITHUB_OUTPUT"
          else
              echo 'platforms=amd64' >> "$GITHUB_OUTPUT"
          fi
      - name: Publish
        uses: docker/build-push-action@v3
        with:
          # Without context, .dockerignore is not respected?
          # https://stackoverflow.com/a/74552407/514684
          context: .
          platforms: '${{ steps.platforms.outputs.platforms }}'
          push: ${{ github.ref == 'refs/heads/master' }}
          tags: '${{ secrets.DOCKERHUB_USERNAME }}/cimple:latest'