Skip to content

chore(docs): Set DANGERZONE_DEV envvar when testing on Windows #6848

chore(docs): Set DANGERZONE_DEV envvar when testing on Windows

chore(docs): Set DANGERZONE_DEV envvar when testing on Windows #6848

Workflow file for this run

name: Tests
on:
pull_request:
push:
branches:
- main
- "test/**"
schedule:
- cron: "2 0 * * *" # Run every day at 02:00 UTC.
workflow_dispatch:
permissions:
actions: read # for detecting the Github Actions environment.
env:
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@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Install dev. dependencies
run: |-
apt-get update
apt-get install -y git make python3 pipx --no-install-recommends
pipx install poetry
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install Python dependencies
run: poetry install
- 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"
windows:
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- runner: windows-2022
- runner: windows-2025
env:
DANGERZONE_DEV: "1"
# NOTE: We have to set the encoding for this run to UTF-8, else we get an
# enoding error when Dangerzone attempts to display its banner, since the
# default seems to be CP-1252:
#
# File "D:\a\dangerzone\dangerzone\dangerzone\cli.py", line 225, in display_banner
# print(Back.BLACK + Fore.YELLOW + Style.DIM + "\u256d\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e")
# ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# File "C:\hostedtoolcache\windows\Python\3.13.7\x64\Lib\encodings\cp1252.py", line 19, in encode
# return codecs.charmap_encode(input,self.errors,encoding_table)[0]
# ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# UnicodeEncodeError: 'charmap' codec can't encode characters in position 14-41: character maps to <undefined>
PYTHONIOENCODING: UTF-8
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.13"
- run: pip install poetry
- run: poetry install
- name: Cache mazette assets
id: cache-mazette
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |
share/tessdata/
share/vendor/
share/machine.tar
key: v1-mazette-windows-${{ hashFiles('./mazette.lock') }}
- name: Install mazette assets
if: steps.cache-mazette.outputs.cache-hit != 'true'
run: poetry run mazette install
- name: Check cosign is present
run: ls share/vendor
- name: Use the testing image and key
run: |-
cp tests/assets/dangerzone-testing.pub share/freedomofpress-dangerzone.pub
echo "ghcr.io/freedomofpress/dangerzone-testing/main/v1" > share/image-name.txt
- uses: imjasonh/setup-crane@59c71e96a00b28651f10369ba3359a6d730740a0 # v0.6
- name: Get the digest of the latest image
id: image-digest
shell: bash
run: echo "digest=$(crane digest $(cat share/image-name.txt):latest)" >> $GITHUB_OUTPUT
- name: Cache container image archive
id: cache-container
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: share/container.tar
key: v1-container-tar-${{ runner.arch }}-${{ steps.image-digest.outputs.digest }}
- name: Download the container image as a tar archive
if: steps.cache-container.outputs.cache-hit != 'true'
env:
DANGERZONE_DEV: "1"
run: >-
poetry run dangerzone-image prepare-archive
--output share/container.tar
# NOTE: We have noticed that the `windows-2022` runner image has WSL
# installed, but its kernel is old (plus, the default version is WSL1).
# This means that `wsl --status` fails, which by extension means that our
# `dangerzone-cli` command and its WSL detection will fail.
#
# For this reason, we prefer to run `wsl --update` before the tests.
# Microsoft's WSL update servers occasionally return HTTP 403, so retry
# before failing the job.
- name: Update WSL
shell: pwsh
run: |
$ok = $false
for ($i = 1; $i -le 5; $i++) {
wsl --update
if ($LASTEXITCODE -eq 0) { $ok = $true; break }
Write-Host "wsl --update attempt $i failed (exit $LASTEXITCODE), retrying..."
Start-Sleep -Seconds 15
}
if (-not $ok) { exit 1 }
- name: Smoke test
run: poetry run dangerzone-cli .\tests\test_docs\sample-pdf.pdf --ocr-lang eng --debug
- name: Run CLI tests
run: poetry run make test
- name: Set up .NET CLI environment
uses: actions/setup-dotnet@9a946fdbd5fb07b82b2f5a4466058b876ab72bb2 # v5.3.0
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
if: matrix.runner == 'windows-2025'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: Dangerzone.msi
path: "dist/Dangerzone.msi"
if-no-files-found: error
compression-level: 0
# See https://github.com/abiosoft/colima/issues/970
macOS-arm64:
uses: ./.github/workflows/ci_macos.yml
with:
runner: macos-15
arch: arm64
# Run Intel tests only on scheduled/manual runs (they take ~2.5 hours).
# See https://github.com/freedomofpress/dangerzone/issues/1338
macOS-intel:
if: github.event_name != 'pull_request'
uses: ./.github/workflows/ci_macos.yml
with:
runner: macos-15-intel
arch: x86_64
build-deb:
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: "26.04"
- distro: ubuntu
version: "25.10"
- distro: debian
version: bookworm
- distro: debian
version: trixie
steps:
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.11"
- name: Install mazette tool
run: |
sudo apt install pipx
pipx install poetry
poetry install
- name: Cache mazette assets
id: cache-mazette
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |
share/vendor/
key: v1-mazette-linux-x86_64-${{ hashFiles('./mazette.lock') }}
- name: Install mazette
if: steps.cache-mazette.outputs.cache-hit != 'true'
run: poetry run mazette install
- name: Get the dev environment
run: |
./dev_scripts/env.py \
--distro ${{ matrix.distro }} \
--version ${{ matrix.version }} \
build-dev --sync
- name: Use the testing image and key
run: |-
cp tests/assets/dangerzone-testing.pub share/freedomofpress-dangerzone.pub
echo "ghcr.io/freedomofpress/dangerzone-testing/main/v1" > share/image-name.txt
- uses: imjasonh/setup-crane@59c71e96a00b28651f10369ba3359a6d730740a0 # v0.6
- name: Get the digest of the latest image
id: image-digest
run: echo "digest=$(crane digest $(cat share/image-name.txt):latest)" >> $GITHUB_OUTPUT
- name: Cache container image archive
id: cache-container
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: share/container.tar
key: v1-container-tar-${{ runner.arch }}-${{ steps.image-digest.outputs.digest }}
- name: Download the container image as a tar archive
if: steps.cache-container.outputs.cache-hit != 'true'
env:
DANGERZONE_DEV: "1"
run: >-
poetry run dangerzone-image prepare-archive
--output share/container.tar
- name: Build Dangerzone .deb packages
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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: dangerzone.deb
path: "deb_dist/dangerzone_*_*.deb"
if-no-files-found: error
compression-level: 0
- name: Upload Dangerzone-full .deb
if: matrix.distro == 'debian' && matrix.version == 'bookworm'
uses: actions/upload-artifact@v6
with:
name: dangerzone-full.deb
path: "deb_dist/dangerzone-full_*_*.deb"
if-no-files-found: error
compression-level: 0
install-deb:
name: "install-deb (${{ matrix.distro }} ${{ matrix.version }})${{ matrix.full && ' [full]' || '' }}"
runs-on: ubuntu-latest
needs:
- build-deb
strategy:
fail-fast: false
matrix:
include:
- distro: ubuntu
version: "22.04"
full: false
- distro: ubuntu
version: "24.04"
full: false
- distro: ubuntu
version: "25.10"
full: false
- distro: ubuntu
version: "26.04"
full: false
- distro: debian
version: bookworm
full: true
- distro: debian
version: bookworm
full: false
- distro: debian
version: trixie
full: false
env:
BUILD_FLAG: ${{ matrix.full && '--full' || '' }}
PKG_PREFIX: dangerzone${{ matrix.full && '-full' || '' }}
steps:
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.10"
- name: Download ${{ env.PKG_PREFIX }}.deb
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: ${{ env.PKG_PREFIX }}.deb
path: "deb_dist/"
- name: Build end-user environment
run: |
./dev_scripts/env.py --distro ${{ matrix.distro }} \
--version ${{ matrix.version }} \
build ${{ env.BUILD_FLAG }}
- if: ${{ !matrix.full }}
name: Download container image
run: |
./dev_scripts/env.py --distro ${{ matrix.distro }} \
--version ${{ matrix.version }} \
run dangerzone-image upgrade
- 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 --debug
- 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}})${{ matrix.full && ' [full]' || '' }}"
runs-on: ubuntu-latest
strategy:
matrix:
distro: ["fedora"]
version: ["43", "44"]
full: [true, false]
env:
RPM_PREFIX: dangerzone${{ matrix.full && '-full' || '' }}
BUILD_FLAG: ${{ matrix.full && '--full' || '' }}
steps:
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Install mazette tool
run: |
sudo apt install pipx
pipx install poetry
poetry install
- name: Cache mazette assets
id: cache-mazette
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |-
share/tessdata/
share/vendor/
key: v1-mazette-linux-${{ hashFiles('./mazette.lock') }}
- name: Install mazette assets
if: steps.cache-mazette.outputs.cache-hit != 'true'
run: poetry run mazette install
- name: Get the dev environment
run: |
./dev_scripts/env.py \
--distro ${{ matrix.distro }} \
--version ${{ matrix.version }} \
build-dev --sync
- if: matrix.full
name: Use the testing image and key
run: |-
cp tests/assets/dangerzone-testing.pub share/freedomofpress-dangerzone.pub
echo "ghcr.io/freedomofpress/dangerzone-testing/main/v1" > share/image-name.txt
- if: matrix.full
uses: imjasonh/setup-crane@59c71e96a00b28651f10369ba3359a6d730740a0 # v0.6
- if: matrix.full
name: Get the digest of the latest image
id: image-digest
run: echo "digest=$(crane digest $(cat share/image-name.txt):latest)" >> $GITHUB_OUTPUT
- if: matrix.full
name: Cache container image archive
id: cache-container
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: share/container.tar
key: v1-container-tar-${{ runner.arch }}-${{ steps.image-digest.outputs.digest }}
- if: matrix.full && steps.cache-container.outputs.cache-hit != 'true'
name: Download the container image as a tar archive
env:
DANGERZONE_DEV: "1"
run: >-
poetry run dangerzone-image prepare-archive --output share/container.tar
- name: Build ${{ env.RPM_PREFIX }}.rpm
run: |
./dev_scripts/env.py --distro ${{ matrix.distro }} --version ${{ matrix.version }} \
run --dev --no-gui ./dangerzone/install/linux/build-rpm.py ${{ env.BUILD_FLAG }}
- name: Upload ${{ env.RPM_PREFIX }}.rpm
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ env.RPM_PREFIX }}-${{ matrix.distro }}-${{ matrix.version }}.rpm
path: dist/${{ env.RPM_PREFIX }}-*.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 ${{ env.BUILD_FLAG }}
- if: ${{ !matrix.full }}
name: Download container image
run: |
./dev_scripts/env.py --distro ${{ matrix.distro }} --version ${{ matrix.version }} \
run dangerzone-image upgrade
- 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 --debug
- 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
strategy:
matrix:
include:
- distro: ubuntu
version: "22.04"
- distro: ubuntu
version: "24.04"
- distro: ubuntu
version: "26.04"
- distro: ubuntu
version: "25.10"
- distro: debian
version: bookworm
- distro: debian
version: trixie
- distro: debian
version: forky
- distro: fedora
version: "43"
- distro: fedora
version: "44"
steps:
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.11"
- name: Install mazette tool
run: |
sudo apt install pipx
pipx install poetry
poetry install
- name: Cache mazette assets
id: cache-mazette
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |
share/tessdata/
share/vendor/
key: v1-mazette-linux-${{ hashFiles('./mazette.lock') }}
- name: Install mazette assets
if: steps.cache-mazette.outputs.cache-hit != 'true'
run: poetry run mazette install
- 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: Use the testing image and key
run: |-
cp tests/assets/dangerzone-testing.pub share/freedomofpress-dangerzone.pub
echo "ghcr.io/freedomofpress/dangerzone-testing/main/v1" > share/image-name.txt
- uses: imjasonh/setup-crane@59c71e96a00b28651f10369ba3359a6d730740a0 # v0.6
- name: Get the digest of the latest image
id: image-digest
run: echo "digest=$(crane digest $(cat share/image-name.txt):latest)" >> $GITHUB_OUTPUT
- name: Cache container image archive
id: cache-container
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: share/container.tar
key: v1-container-tar-${{ runner.arch }}-${{ steps.image-digest.outputs.digest }}
- name: Download the container image as a tar archive
if: steps.cache-container.outputs.cache-hit != 'true'
env:
DANGERZONE_DEV: "1"
run: >-
poetry run dangerzone-image prepare-archive
--output share/container.tar
- name: Run CI tests
run: |-
# Run the tests with no network connection, using the `--no-network`
# flag, to ensure that Dangerzone can run in airgapped installations.
#
# GUI tests run headless via QT_QPA_PLATFORM=offscreen (set in
# tests/gui/conftest.py), so no X server is needed. We pass --no-gui
# to env.py so it doesn't try to forward the host's X socket into the
# container.
./dev_scripts/env.py \
--distro ${{ matrix.distro }} --version ${{ matrix.version }} \
run --dev --no-gui --no-network \
bash -c 'cd dangerzone; poetry run make test'
end-to-end-test:
name: "Sandbox upgrade E2E test"
runs-on: ubuntu-latest
env:
DANGERZONE_DEV: "1"
steps:
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.11"
- name: Install mazette tool
run: |
sudo apt install pipx
pipx install poetry
poetry install
- name: Cache mazette assets
id: cache-mazette
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |
share/tessdata/
share/vendor/
key: v1-mazette-linux-${{ hashFiles('./mazette.lock') }}
- name: Install mazette assets
if: steps.cache-mazette.outputs.cache-hit != 'true'
run: poetry run mazette install
- name: Use the testing image and key
run: |-
cp tests/assets/dangerzone-testing.pub share/freedomofpress-dangerzone.pub
echo "ghcr.io/freedomofpress/dangerzone-testing/main/v1" > share/image-name.txt
- name: Download the old container image as an archive
run: >-
poetry run dangerzone-image prepare-archive
--image $(cat share/image-name.txt):old-latest
--output /tmp/old-container.tar
- name: Load the old container image
run: >-
poetry run dangerzone-image load-archive
--force /tmp/old-container.tar
- name: Run a conversion
run: |
poetry run dangerzone-cli ./tests/test_docs/sample-pdf.pdf
- name: Update the settings so they check for updates
run: |
jq '.updater_check_all = true' ~/.config/dangerzone/settings.json > temp.json && mv temp.json ~/.config/dangerzone/settings.json
- uses: imjasonh/setup-crane@59c71e96a00b28651f10369ba3359a6d730740a0 # v0.6
- name: Get the digest of the latest image
id: latest
run: echo "digest=$(crane digest $(cat share/image-name.txt):latest)" >> $GITHUB_OUTPUT
- name: Run another conversion
run: |
poetry run dangerzone-cli ./tests/test_docs/sample-pdf.pdf
- name: Ensure the container has been upgraded
run: |
DIGEST=$(podman images $(cat share/image-name.txt | head -1) --format "{{.Digest}}")
EXPECTED_DIGEST=${{ steps.latest.outputs.digest }}
if [[ $DIGEST != $EXPECTED_DIGEST ]]; then
exit 1
fi