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@v4 - 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@v4 - name: Set up Python uses: actions/setup-python@v5 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 '${{ matrix.configuration }}/install' - name: Upload binaries uses: actions/upload-artifact@v4 with: name: 'cimple-${{ matrix.compiler }}-${{ matrix.configuration }}' path: './build/${{ matrix.configuration }}/install/' if-no-files-found: error - name: Run tests run: make '${{ matrix.configuration }}/report' - name: Upload test report uses: actions/upload-artifact@v4 with: name: 'test-report-${{ matrix.compiler }}-${{ matrix.configuration }}' path: './build/${{ matrix.configuration }}/test_report/' if-no-files-found: error if: always() - name: Run Valgrind tests run: make '${{ matrix.configuration }}/valgrind' coverage: runs-on: ubuntu-latest name: 'Code coverage' steps: - name: Checkout uses: actions/checkout@v4 - 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@v4 with: name: coverage path: ./build/coverage/html/ if-no-files-found: error flame_graphs: runs-on: ubuntu-latest name: 'Flame graphs' steps: - name: Checkout uses: actions/checkout@v4 - 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 debug/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 DEBUGINFOD_URLS='https://debuginfod.ubuntu.com' make debug/flame_graphs - name: Upload flame graphs uses: actions/upload-artifact@v4 with: name: flame_graphs path: ./build/debug/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@v4 - name: Download test report - clang/debug uses: actions/download-artifact@v4 with: name: test-report-clang-debug path: /tmp/reports/test_report_clang_debug/ - name: Download test report - clang/release uses: actions/download-artifact@v4 with: name: test-report-clang-release path: /tmp/reports/test_report_clang_release/ - name: Download coverage report uses: actions/download-artifact@v4 with: name: coverage path: /tmp/reports/coverage - name: Download flame graphs uses: actions/download-artifact@v4 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@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to Docker Hub uses: docker/login-action@v3 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@v5 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'