name: Tests on: pull_request: push: branches: - main - "test/**" schedule: - cron: "2 0 * * *" # Run every day at 02:00 UTC. workflow_dispatch: permissions: packages: write env: REGISTRY_USER: ${{ github.actor }} REGISTRY_PASSWORD: ${{ github.token }} IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} QT_SELECT: "qt6" # Disable multiple concurrent runs on the same branch # When a new CI build is triggered, it will cancel the # other in-progress ones (for the same branch) concurrency: group: ${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: #run-lint: # runs-on: ubuntu-latest # container: # image: debian:bookworm # steps: # - uses: actions/checkout@v4 # - name: Install dev. dependencies # run: |- # apt-get update # apt-get install -y git make python3 python3-poetry --no-install-recommends # poetry install --only lint,test # - name: Run linters to enforce code style # run: poetry run make lint # - name: Check that the QA script is up to date with the docs # run: "./dev_scripts/qa.py --check-refs" # This is already built daily by the "build.yml" file # But we also want to include this in the checks that run on each push. build-container-image: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Get current date id: date run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT - name: Cache container image id: cache-container-image uses: actions/cache@v4 with: key: v5-${{ steps.date.outputs.date }}-${{ hashFiles('Dockerfile', 'dangerzone/conversion/*.py', 'dangerzone/container_helpers/*', 'install/common/build-image.py') }} path: |- share/container.tar share/image-id.txt - name: Build Dangerzone container image if: ${{ steps.cache-container-image.outputs.cache-hit != 'true' }} run: | python3 ./install/common/build-image.py - name: Upload container image uses: actions/upload-artifact@v4 with: name: container.tar path: share/container.tar windows: runs-on: windows-latest env: DUMMY_CONVERSION: 1 steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.12" - run: pip install poetry - run: poetry install - name: Cache inventory id: cache-inventory uses: actions/cache@v4 with: path: share/tessdata/ key: v1-inventory-windows-${{ hashFiles('./inventory.lock') }} - name: Sync inventory if: steps.cache-inventory.outputs.cache-hit != 'true' run: | poetry run python .\dev_scripts\inventory.py sync - name: Run CLI tests run: poetry run make test - name: Set up .NET CLI environment uses: actions/setup-dotnet@v4 with: dotnet-version: "8.x" - name: Install WiX Toolset run: dotnet tool install --global wix --version 5.0.2 - name: Add WiX UI extension run: wix extension add --global WixToolset.UI.wixext/5.0.2 - name: Build the MSI installer # NOTE: This also builds the .exe internally. run: poetry run .\install\windows\build-app.bat - name: Upload MSI installer uses: actions/upload-artifact@v4 with: name: Dangerzone.msi path: "dist/Dangerzone.msi" if-no-files-found: error compression-level: 0 #macOS: # name: "macOS (${{ matrix.arch }})" # runs-on: ${{ matrix.runner }} # strategy: # matrix: # include: # - runner: macos-latest # CPU type: Apple Silicon (M1) # arch: arch64 # - runner: macos-13 # CPU type: Intel x86_64 # arch: x86_64 # env: # DUMMY_CONVERSION: 1 # steps: # - uses: actions/checkout@v4 # - uses: actions/setup-python@v5 # with: # python-version: "3.12" # - run: pip install poetry # - run: poetry install # - name: Cache inventory # id: cache-inventory # uses: actions/cache@v4 # with: # path: share/tessdata/ # key: v1-inventory-darwin-${{ matrix.arch }}-${{ hashFiles('./inventory.lock') }} # - name: Sync inventory # if: steps.cache-inventory.outputs.cache-hit != 'true' # run: poetry run python3 ./dev_scripts/inventory.py sync # - name: Run CLI tests # run: poetry run make test # - name: Build macOS app # run: poetry run python ./install/macos/build-app.py # - name: Upload macOS app # uses: actions/upload-artifact@v4 # with: # name: Dangerzone-${{ matrix.arch }}.app # path: "dist/Dangerzone.app" # if-no-files-found: error # compression-level: 0 #build-deb: # needs: # - build-container-image # name: "build-deb (${{ matrix.distro }} ${{ matrix.version }})" # runs-on: ubuntu-latest # strategy: # matrix: # include: # - distro: ubuntu # version: "22.04" # - distro: ubuntu # version: "24.04" # - distro: ubuntu # version: "24.10" # - distro: ubuntu # version: "25.04" # - distro: debian # version: bullseye # - distro: debian # version: bookworm # - distro: debian # version: trixie # steps: # - name: Checkout # uses: actions/checkout@v4 # - uses: actions/setup-python@v5 # with: # python-version: "3.11" # - name: Login to GHCR # run: | # echo ${{ github.token }} | podman login ghcr.io -u USERNAME --password-stdin # - name: Get the dev environment # run: | # ./dev_scripts/env.py \ # --distro ${{ matrix.distro }} \ # --version ${{ matrix.version }} \ # build-dev --sync # - name: Get current date # id: date # run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT # - name: Restore container cache # uses: actions/cache/restore@v4 # with: # key: v5-${{ steps.date.outputs.date }}-${{ hashFiles('Dockerfile', 'dangerzone/conversion/*.py', 'dangerzone/container_helpers/*', 'install/common/build-image.py') }} # path: |- # share/container.tar # share/image-id.txt # fail-on-cache-miss: true # - name: Build Dangerzone .deb # run: | # ./dev_scripts/env.py --distro ${{ matrix.distro }} \ # --version ${{ matrix.version }} \ # run --dev --no-gui ./dangerzone/install/linux/build-deb.py # - name: Upload Dangerzone .deb # if: matrix.distro == 'debian' && matrix.version == 'bookworm' # uses: actions/upload-artifact@v4 # with: # name: dangerzone.deb # path: "deb_dist/dangerzone_*_*.deb" # if-no-files-found: error # compression-level: 0 #install-deb: # name: "install-deb (${{ matrix.distro }} ${{ matrix.version }})" # runs-on: ubuntu-latest # needs: # - build-deb # strategy: # matrix: # include: # - distro: ubuntu # version: "22.04" # - distro: ubuntu # version: "24.04" # - distro: ubuntu # version: "24.10" # - distro: ubuntu # version: "25.04" # - distro: debian # version: bullseye # - distro: debian # version: bookworm # - distro: debian # version: trixie # steps: # - name: Checkout # uses: actions/checkout@v4 # - uses: actions/setup-python@v5 # with: # python-version: "3.10" # - name: Download Dangerzone .deb # uses: actions/download-artifact@v4 # with: # name: dangerzone.deb # path: "deb_dist/" # - name: Build end-user environment # run: | # ./dev_scripts/env.py --distro ${{ matrix.distro }} \ # --version ${{ matrix.version }} \ # build # - name: Run a test command # run: | # ./dev_scripts/env.py --distro ${{ matrix.distro }} \ # --version ${{ matrix.version }} \ # run dangerzone-cli dangerzone/tests/test_docs/sample-pdf.pdf --ocr-lang eng # - name: Check that the Dangerzone GUI imports work # run: | # ./dev_scripts/env.py --distro ${{ matrix.distro }} \ # --version ${{ matrix.version }} \ # run dangerzone --help #build-install-rpm: # name: "build-install-rpm (${{ matrix.distro }} ${{matrix.version}})" # runs-on: ubuntu-latest # needs: # - build-container-image # strategy: # matrix: # distro: ["fedora"] # version: ["40", "41", "42"] # steps: # - name: Checkout # uses: actions/checkout@v4 # - name: Login to GHCR # run: | # echo ${{ github.token }} | podman login ghcr.io -u USERNAME --password-stdin # - name: Get the dev environment # run: | # ./dev_scripts/env.py \ # --distro ${{ matrix.distro }} \ # --version ${{ matrix.version }} \ # build-dev --sync # - name: Get current date # id: date # run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT # - name: Restore container image # uses: actions/cache/restore@v4 # with: # key: v5-${{ steps.date.outputs.date }}-${{ hashFiles('Dockerfile', 'dangerzone/conversion/*.py', 'dangerzone/container_helpers/*', 'install/common/build-image.py') }} # path: |- # share/container.tar # share/image-id.txt # fail-on-cache-miss: true # - name: Build Dangerzone .rpm # run: | # ./dev_scripts/env.py --distro ${{ matrix.distro }} --version ${{ matrix.version }} \ # run --dev --no-gui ./dangerzone/install/linux/build-rpm.py # - name: Upload Dangerzone .rpm # uses: actions/upload-artifact@v4 # with: # name: dangerzone-${{ matrix.distro }}-${{ matrix.version }}.rpm # path: "dist/dangerzone-*.x86_64.rpm" # if-no-files-found: error # compression-level: 0 # # Reclaim some space in this step, now that the dev environment is no # # longer necessary. Previously, we encountered out-of-space issues while # # running this CI job. # - name: Reclaim some storage space # run: podman system reset -f # - name: Build end-user environment # run: | # ./dev_scripts/env.py --distro ${{ matrix.distro }} \ # --version ${{ matrix.version }} \ # build # - name: Run a test command # run: | # ./dev_scripts/env.py --distro ${{ matrix.distro }} --version ${{ matrix.version }} \ # run dangerzone-cli dangerzone/tests/test_docs/sample-pdf.pdf --ocr-lang eng # - name: Check that the Dangerzone GUI imports work # run: | # ./dev_scripts/env.py --distro ${{ matrix.distro }} --version ${{ matrix.version }} \ # run dangerzone --help #run-tests: # name: "run tests (${{ matrix.distro }} ${{ matrix.version }})" # runs-on: ubuntu-latest # needs: # - build-container-image # strategy: # matrix: # include: # - distro: ubuntu # version: "22.04" # - distro: ubuntu # version: "24.04" # - distro: ubuntu # version: "24.10" # - distro: ubuntu # version: "25.04" # - distro: debian # version: bullseye # - distro: debian # version: bookworm # - distro: debian # version: trixie # - distro: fedora # version: "40" # - distro: fedora # version: "41" # - distro: fedora # version: "42" # steps: # - name: Checkout # uses: actions/checkout@v4 # - uses: actions/setup-python@v5 # with: # python-version: "3.11" # - name: Install inventory dependencies # run: | # sudo apt install pipx # pipx install poetry # poetry install # - name: Cache inventory # id: cache-inventory # uses: actions/cache@v4 # with: # path: share/tessdata/ # key: v1-inventory-linux-${{ hashFiles('./inventory.lock') }} # - name: Sync inventory # if: steps.cache-inventory.outputs.cache-hit != 'true' # run: poetry run python3 ./dev_scripts/inventory.py sync # - name: Login to GHCR # run: | # echo ${{ github.token }} | podman login ghcr.io -u USERNAME --password-stdin # - name: Get current date # id: date # run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT # - name: Get the dev environment # run: | # ./dev_scripts/env.py \ # --distro ${{ matrix.distro }} \ # --version ${{ matrix.version }} \ # build-dev --sync # - name: Restore container image # uses: actions/cache/restore@v4 # with: # key: v5-${{ steps.date.outputs.date }}-${{ hashFiles('Dockerfile', 'dangerzone/conversion/*.py', 'dangerzone/container_helpers/*', 'install/common/build-image.py') }} # path: |- # share/container.tar # share/image-id.txt # fail-on-cache-miss: true # - name: Setup xvfb (Linux) # run: | # sudo apt update # # Stuff copied wildly from several stackoverflow posts # sudo apt-get install -y xvfb libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 libxcb-shape0 libglib2.0-0 libgl1-mesa-dev '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev # # start xvfb in the background # sudo /usr/bin/Xvfb $DISPLAY -screen 0 1280x1024x24 & # - name: Run CI tests # run: |- # # Pass the -ac Xserver flag, to disable host-based access controls. # # This should be used ONLY for testing [1]. If we don't pass this # # flag, the Podman container is not authorized [2] to access the Xvfb # # server. # # # # [1] From https://www.x.org/releases/X11R6.7.0/doc/Xserver.1.html#sect4: # # # # disables host-based access control mechanisms. Enables access by # # any host, and permits any host to modify the access control # # list. Use with extreme caution. This option exists primarily for # # running test suites remotely. # # # # [2] Fails with "Authorization required, but no authorization # # protocol specified". However, we have verified with strace(1) # # that the command in the Podman container can read the Xauthority # # file successfully. # xvfb-run -s '-ac' ./dev_scripts/env.py --distro ${{ matrix.distro }} --version ${{ matrix.version }} run --dev \ # bash -c 'cd dangerzone; poetry run make test' # - name: Upload PDF diffs # uses: actions/upload-artifact@v4 # with: # name: pdf-diffs-${{ matrix.distro }}-${{ matrix.version }} # path: tests/test_docs/diffs/*.jpeg # # Always run this step to publish test results, even on failures # if: ${{ always() }}