Switch from CircleCI runners to Github actions.

As part of this change, the dev (build) and end-user test images names
changed from `dangerzone.rocks/*` to `dangerzone/`, to allow using
another container registry. For the needs of our CI, we use ghcr.io.
This commit is contained in:
Alexis Métaireau 2024-09-06 17:38:23 +02:00
parent eee405e29e
commit d31bdf32bc
No known key found for this signature in database
GPG key ID: C65C7A89A8FFC56E
5 changed files with 386 additions and 704 deletions

View file

@ -1,622 +0,0 @@
version: 2.1
aliases:
- &install-podman
name: Install Podman in Ubuntu Focal
command: ./install/linux/install-podman-ubuntu-focal.sh
# FIXME: Remove the following step once we drop Ubuntu Focal support. The
# python-all dependency is an artificial requirement due to an stdeb bug
# prior to v0.9.1. See:
#
# * https://github.com/astraw/stdeb/issues/153
# * https://github.com/freedomofpress/dangerzone/issues/292#issuecomment-1349967888
- &install-python-all
name: Install python-all package
command: |
export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true
apt-get update
apt-get install -y python-all
- &install-dependencies-deb
name: Install dependencies (deb)
command: |
export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true
apt-get update
apt-get install -y dh-python python3 python3-stdeb
- &install-dependencies-rpm
name: Install dependencies (rpm)
command: |
dnf install -y rpm-build python3 python3-devel python3-poetry-core pipx
pipx install poetry
- &build-deb
name: Build the .deb package
command: |
./install/linux/build-deb.py
ls -lh deb_dist/
- &build-rpm
name: Build the .rpm package
command: |
PATH=/root/.local/bin:$PATH ./install/linux/build-rpm.py
ls -lh dist/
- &build-rpm-qubes
name: Build the Qubes .rpm package
command: |
PATH=/root/.local/bin:$PATH ./install/linux/build-rpm.py --qubes
ls -lh dist/
- &calculate-cache-key
name: Caculating container cache key
command: |
mkdir -p /caches/
cd dangerzone/conversion/
cat common.py doc_to_pixels.py pixels_to_pdf.py | sha1sum | cut -d' ' -f1 > /caches/cache-id.txt
cd ../../
- &restore-cache
key: v1-{{ checksum "Dockerfile" }}-{{ checksum "/caches/cache-id.txt" }}
paths:
- /caches/container.tar.gz
- /caches/image-id.txt
- &copy-image
name: Copy container image into package
command: |
cp /caches/container.tar.gz share/
cp /caches/image-id.txt share/
jobs:
run-lint:
docker:
- image: debian:bookworm
resource_class: small
steps:
- checkout
- run:
name: Install dev. dependencies
# Install only the necessary packages to run our linters.
#
# We run poetry with --no-ansi, to sidestep a Poetry bug that
# currently exists in 1.3. See:
# https://github.com/freedomofpress/dangerzone/issues/292#issuecomment-1351368122
command: |
apt-get update
apt-get install -y git make python3 python3-poetry --no-install-recommends
poetry install --no-ansi --only lint,test
- run:
name: Run linters to enforce code style
command: poetry run make lint
- run:
name: Check that the QA script is up to date with the docs
command: ./dev_scripts/qa.py --check-refs
build-container-image:
machine:
image: ubuntu-2004:202111-01
steps:
- checkout
- run: *install-podman
- run:
name: Prepare cache directory
command: |
sudo mkdir -p /caches
sudo chown -R $USER:$USER /caches
- run: *calculate-cache-key
- restore_cache: *restore-cache
# setup_remote_docker
- run:
name: Build Dangerzone image
command: |
if [ -f "/caches/container.tar.gz" ]; then
echo "Already cached, skipping"
else
sudo pip3 install poetry
python3 ./install/common/build-image.py
fi
- run:
name: Save Dangerzone image and image-id.txt to cache
command: |
if [ -f "/caches/container.tar.gz" ]; then
echo "Already cached, skipping"
else
mkdir -p /caches
podman save -o /caches/container.tar dangerzone.rocks/dangerzone
gzip -f /caches/container.tar
podman image ls dangerzone.rocks/dangerzone | grep "dangerzone.rocks/dangerzone" | tr -s ' ' | cut -d' ' -f3 > /caches/image-id.txt
fi
- run: *calculate-cache-key
- save_cache:
key: v1-{{ checksum "Dockerfile" }}-{{ checksum "/caches/cache-id.txt" }}
paths:
- /caches/container.tar.gz
- /caches/image-id.txt
convert-test-docs:
machine:
image: ubuntu-2004:202111-01
steps:
- checkout
- run: *install-podman
- run:
name: Install poetry dependencies
command: |
sudo pip3 install poetry
# This flag is important, due to an open upstream Poetry issue:
# https://github.com/python-poetry/poetry/issues/7184
poetry install --no-ansi
- run:
name: Install test dependencies
command: |
sudo apt-get install -y libqt5gui5 libxcb-cursor0 --no-install-recommends
- run:
name: Prepare cache directory
command: |
sudo mkdir -p /caches
sudo chown -R $USER:$USER /caches
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run:
name: run automated tests
command: |
poetry run make test
ci-ubuntu-noble:
machine:
image: ubuntu-2004:202111-01
steps:
- checkout
- run: *install-podman
- run:
name: Prepare cache directory
command: |
sudo mkdir -p /caches
sudo chown -R $USER:$USER /caches
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run:
name: Prepare Dangerzone environment
command: |
./dev_scripts/env.py --distro ubuntu --version 24.04 build-dev
- run:
name: Run CI tests
command: |
./dev_scripts/env.py --distro ubuntu --version 24.04 run --dev \
bash -c 'cd dangerzone; poetry run make test'
ci-ubuntu-mantic:
machine:
image: ubuntu-2004:202111-01
steps:
- checkout
- run: *install-podman
- run:
name: Prepare cache directory
command: |
sudo mkdir -p /caches
sudo chown -R $USER:$USER /caches
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run:
name: Prepare Dangerzone environment
command: |
./dev_scripts/env.py --distro ubuntu --version 23.10 build-dev
- run:
name: Run CI tests
command: |
./dev_scripts/env.py --distro ubuntu --version 23.10 run --dev \
bash -c 'cd dangerzone; poetry run make test'
ci-ubuntu-jammy:
machine:
image: ubuntu-2004:202111-01
steps:
- checkout
- run: *install-podman
- run:
name: Prepare cache directory
command: |
sudo mkdir -p /caches
sudo chown -R $USER:$USER /caches
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run:
name: Prepare Dangerzone environment
command: |
./dev_scripts/env.py --distro ubuntu --version 22.04 build-dev
- run:
name: Run CI tests
command: |
./dev_scripts/env.py --distro ubuntu --version 22.04 run --dev \
bash -c 'cd dangerzone; poetry run make test'
ci-ubuntu-focal:
machine:
image: ubuntu-2004:202111-01
steps:
- checkout
- run: *install-podman
- run:
name: Prepare cache directory
command: |
sudo mkdir -p /caches
sudo chown -R $USER:$USER /caches
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run:
name: Prepare Dangerzone environment
command: |
./dev_scripts/env.py --distro ubuntu --version 20.04 build-dev
- run:
name: Run CI tests
command: |
./dev_scripts/env.py --distro ubuntu --version 20.04 run --dev \
bash -c 'cd dangerzone; poetry run make test'
ci-fedora-40:
machine:
image: ubuntu-2004:202111-01
steps:
- checkout
- run: *install-podman
- run:
name: Prepare cache directory
command: |
sudo mkdir -p /caches
sudo chown -R $USER:$USER /caches
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run:
name: Prepare Dangerzone environment
command: |
./dev_scripts/env.py --distro fedora --version 40 build-dev
- run:
name: Run CI tests
command: |
./dev_scripts/env.py --distro fedora --version 40 run --dev \
bash -c 'cd dangerzone; poetry run make test'
ci-fedora-39:
machine:
image: ubuntu-2004:202111-01
steps:
- checkout
- run: *install-podman
- run:
name: Prepare cache directory
command: |
sudo mkdir -p /caches
sudo chown -R $USER:$USER /caches
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run:
name: Prepare Dangerzone environment
command: |
./dev_scripts/env.py --distro fedora --version 39 build-dev
- run:
name: Run CI tests
command: |
./dev_scripts/env.py --distro fedora --version 39 run --dev \
bash -c 'cd dangerzone; poetry run make test'
ci-debian-trixie:
machine:
image: ubuntu-2004:202111-01
steps:
- checkout
- run: *install-podman
- run:
name: Prepare cache directory
command: |
sudo mkdir -p /caches
sudo chown -R $USER:$USER /caches
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run:
name: Prepare Dangerzone environment
command: |
./dev_scripts/env.py --distro debian --version trixie build-dev
- run:
name: Run CI tests
command: |
./dev_scripts/env.py --distro debian --version trixie run --dev \
bash -c 'cd dangerzone; poetry run make test'
ci-debian-bookworm:
machine:
image: ubuntu-2004:202111-01
steps:
- checkout
- run: *install-podman
- run:
name: Prepare cache directory
command: |
sudo mkdir -p /caches
sudo chown -R $USER:$USER /caches
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run:
name: Prepare Dangerzone environment
command: |
./dev_scripts/env.py --distro debian --version bookworm build-dev
- run:
name: Run CI tests
command: |
./dev_scripts/env.py --distro debian --version bookworm run --dev \
bash -c 'cd dangerzone; poetry run make test'
# NOTE: Making CI tests work in Debian Bullseye requires some tip-toeing
# around certain Podman issues, as you'll see below. Read the following for
# more details:
#
# https://github.com/freedomofpress/dangerzone/issues/388
ci-debian-bullseye:
machine:
image: ubuntu-2204:2023.04.2
steps:
- checkout
- run: *install-podman
- run:
name: Configure Podman for Ubuntu 22.04
command: |
# This config circumvents the following issues:
# * https://github.com/containers/podman/issues/6368
# * https://github.com/containers/podman/issues/10987
mkdir -p ~/.config/containers
cat > ~/.config/containers/containers.conf \<<EOF
[engine]
cgroup_manager="cgroupfs"
events_logger="file"
EOF
- run:
name: Prepare cache directory
command: |
sudo mkdir -p /caches
sudo chown -R $USER:$USER /caches
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run:
name: Prepare Dangerzone environment
command: |
./dev_scripts/env.py --distro debian --version bullseye build-dev
- run:
name: Configure Podman for Debian Bullseye
command: |
# Copy the Podman config into the container image we created for the
# Dangerzone environment.
cp ~/.config/containers/containers.conf containers.conf
cat > Dockerfile.bullseye \<<EOF
FROM dangerzone.rocks/build/debian:bullseye-backports
RUN mkdir -p /home/user/.config/containers
COPY containers.conf /home/user/.config/containers/
EOF
# Create a new image from the Dangerzone environment and re-tag it.
podman build -t dangerzone.rocks/build/debian:bullseye-backports \
-f Dockerfile.bullseye .
- run:
name: Run CI tests
command: |
./dev_scripts/env.py --distro debian --version bullseye run --dev \
bash -c 'cd dangerzone; poetry run make test'
build-ubuntu-noble:
docker:
- image: ubuntu:24.04
resource_class: medium+
steps:
- run: *install-dependencies-deb
- checkout
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run: *build-deb
build-ubuntu-mantic:
docker:
- image: ubuntu:23.10
resource_class: medium+
steps:
- run: *install-dependencies-deb
- checkout
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run: *build-deb
build-ubuntu-jammy:
docker:
- image: ubuntu:22.04
resource_class: medium+
steps:
- run: *install-dependencies-deb
- checkout
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run: *build-deb
build-ubuntu-focal:
docker:
- image: ubuntu:20.04
resource_class: medium+
steps:
- run: *install-dependencies-deb
- run: *install-python-all
- checkout
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run: *build-deb
build-debian-trixie:
docker:
- image: debian:trixie
resource_class: medium+
steps:
- run: *install-dependencies-deb
- checkout
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run: *build-deb
build-debian-bookworm:
docker:
- image: debian:bookworm
resource_class: medium+
steps:
- run: *install-dependencies-deb
- checkout
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run: *build-deb
build-debian-bullseye:
docker:
- image: debian:bullseye
resource_class: medium+
steps:
- run: *install-dependencies-deb
- checkout
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run: *build-deb
build-fedora-40:
docker:
- image: fedora:40
resource_class: medium+
steps:
- run: *install-dependencies-rpm
- checkout
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run: *build-rpm
- run: *build-rpm-qubes
build-fedora-39:
docker:
- image: fedora:39
resource_class: medium+
steps:
- run: *install-dependencies-rpm
- checkout
- run: *calculate-cache-key
- restore_cache: *restore-cache
- run: *copy-image
- run: *build-rpm
- run: *build-rpm-qubes
workflows:
version: 2
build:
jobs:
- run-lint
- build-container-image
- convert-test-docs:
requires:
- build-container-image
- ci-ubuntu-noble:
requires:
- build-container-image
- ci-ubuntu-mantic:
requires:
- build-container-image
- ci-ubuntu-jammy:
requires:
- build-container-image
- ci-ubuntu-focal:
requires:
- build-container-image
- ci-debian-trixie:
requires:
- build-container-image
- ci-debian-bookworm:
requires:
- build-container-image
- ci-debian-bullseye:
requires:
- build-container-image
- ci-fedora-40:
requires:
- build-container-image
- ci-fedora-39:
requires:
- build-container-image
# FIXME: Currently disabled because `stdeb` does not work with Python
# 3.12, which is the default in Ubuntu Noble. See also:
# https://github.com/freedomofpress/dangerzone/issues/773
#
#- build-ubuntu-noble:
# requires:
# - build-container-image
- build-ubuntu-mantic:
requires:
- build-container-image
- build-ubuntu-jammy:
requires:
- build-container-image
- build-ubuntu-focal:
requires:
- build-container-image
- build-debian-bullseye:
requires:
- build-container-image
- build-debian-trixie:
requires:
- build-container-image
- build-debian-bookworm:
requires:
- build-container-image
- build-fedora-40:
requires:
- build-container-image
- build-fedora-39:
requires:
- build-container-image

103
.github/workflows/build.yml vendored Normal file
View file

@ -0,0 +1,103 @@
name: Build dev environments
on:
push:
schedule:
- cron: "0 0 * * *" # Run every day at 00:00 UTC.
env:
IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }}
REGISTRY_USER: ${{ github.actor }}
REGISTRY_PASSWORD: ${{ github.token }}
# Each day, build and publish to ghcr.io:
#
# - the dangerzone/dangerzone container image
# - the dangerzone/build/{debian,ubuntu,fedora}:version
# dev environments used to run the tests
#
# End-user environments are not published to the GHCR because
# they need .rpm or .deb files to be built, which is what we
# want to test.
jobs:
build-dev-environment:
name: "Build dev-env (${{ matrix.distro }}-${{ matrix.version }})"
runs-on: ubuntu-latest
strategy:
matrix:
include:
- distro: ubuntu
version: "20.04"
- distro: ubuntu
version: "22.04"
- distro: ubuntu
version: "23.10"
- distro: ubuntu
version: "24.04"
- distro: debian
version: bullseye
- distro: debian
version: bookworm
- distro: debian
version: trixie
- distro: fedora
version: "39"
- distro: fedora
version: "40"
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Login to GHCR
run: |
echo ${{ github.token }} | podman login ghcr.io -u USERNAME --password-stdin
- name: Build dev environment
run: |
./dev_scripts/env.py --distro ${{ matrix.distro }} \
--version ${{ matrix.version }} \
build-dev --sync
build-container-image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get current date
id: date
run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
- name: Restore container cache
uses: actions/cache@v4
with:
key: v2-${{ steps.date.outputs.date }}-${{ hashFiles('Dockerfile', 'dangerzone/conversion/common.py', 'dangerzone/conversion/doc_to_pixels.py', 'dangerzone/conversion/pixels_to_pdf.py') }}
path: |
share/container.tar.gz
share/image-id.txt
- name: Build Dangerzone image
run: |
if [ -f "share/container.tar.gz" ]; then
echo "Already cached, skipping"
else
sudo apt-get install -y python3-poetry
python3 ./install/common/build-image.py
fi
- name: Load container image
run: |
gunzip -c share/container.tar.gz | podman load
- name: Login to GHCR
run: |
echo ${{ github.token }} | podman login ghcr.io -u USERNAME --password-stdin
- name: Push To GHCR
run: |
podman push \
dangerzone.rocks/dangerzone \
${{ env.IMAGE_REGISTRY }}/dangerzone/dangerzone

View file

@ -4,9 +4,64 @@ on:
pull_request: pull_request:
branches: [ main ] branches: [ main ]
schedule: schedule:
- cron: '0 0 * * *' # Run every day at 00:00 UTC. - cron: "2 0 * * *" # Run every day at 02:00 UTC.
workflow_dispatch:
env:
REGISTRY_USER: ${{ github.actor }}
REGISTRY_PASSWORD: ${{ github.token }}
IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }}
# This is required for running GUI tests on Github Actions
DISPLAY: ":99.0"
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: 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 --no-ansi --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-latest
steps:
- uses: actions/checkout@v4
- name: Restore container cache
uses: actions/cache@v4
with:
key: v2-${{ hashFiles('Dockerfile', 'dangerzone/conversion/common.py', 'dangerzone/conversion/doc_to_pixels.py', 'dangerzone/conversion/pixels_to_pdf.py') }}
path: |-
share/container.tar.gz
share/image-id.txt
- name: Build Dangerzone image
run: |-
if [ -f "share/container.tar.gz" ]; then
echo "Already cached, skipping"
else
sudo apt-get install -y python3-poetry
python3 ./install/common/build-image.py
fi
windows: windows:
runs-on: windows-latest runs-on: windows-latest
env: env:
@ -43,11 +98,26 @@ jobs:
run: poetry run make test run: poetry run make test
build-deb: build-deb:
name: "build-deb (${{ matrix.distro }} ${{ matrix.version }})"
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: needs: build-container-image
target: debian-bookworm strategy:
distro: debian matrix:
version: bookworm include:
- distro: ubuntu
version: "20.04"
- distro: ubuntu
version: "22.04"
- distro: ubuntu
version: "23.10"
- distro: ubuntu
version: "24.04"
- distro: debian
version: bullseye
- distro: debian
version: bookworm
- distro: debian
version: trixie
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@ -56,56 +126,58 @@ jobs:
with: with:
python-version: '3.10' python-version: '3.10'
- name: Build dev environment - name: Login to GHCR
run: | run: |
./dev_scripts/env.py --distro ${{ env.distro }} \ echo ${{ github.token }} | podman login ghcr.io -u USERNAME --password-stdin
--version ${{ env.version }} \
build-dev
- name: Install container build dependencies - name: Get the dev environment
run: sudo apt install pipx && pipx install poetry run: |
./dev_scripts/env.py \
--distro ${{ matrix.distro }} \
--version ${{ matrix.version }} \
build-dev --sync
- name: Build Dangerzone image - name: Restore container cache
run: python3 ./install/common/build-image.py uses: actions/cache@v4
with:
key: v2-${{ hashFiles('Dockerfile', 'dangerzone/conversion/common.py', 'dangerzone/conversion/doc_to_pixels.py', 'dangerzone/conversion/pixels_to_pdf.py') }}
path: |-
share/container.tar.gz
share/image-id.txt
- name: Build Dangerzone .deb - name: Build Dangerzone .deb
run: | run: |
./dev_scripts/env.py --distro ${{ env.distro }} \ ./dev_scripts/env.py --distro ${{ matrix.distro }} \
--version ${{ env.version }} \ --version ${{ matrix.version }} \
run --dev --no-gui ./dangerzone/install/linux/build-deb.py run --dev --no-gui ./dangerzone/install/linux/build-deb.py
- name: Upload Dangerzone .deb - name: Upload Dangerzone .deb
if: matrix.distro == 'debian' && matrix.version == 'trixie'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: dangerzone.deb name: dangerzone.deb
path: "deb_dist/dangerzone_*_all.deb" path: "deb_dist/dangerzone_*_all.deb"
install-deb: install-deb:
name: "install-deb (${{ matrix.distro }} ${{ matrix.version }})"
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build-deb needs: build-deb
strategy: strategy:
matrix: matrix:
include: include:
- target: ubuntu-20.04 - distro: ubuntu
distro: ubuntu
version: "20.04" version: "20.04"
- target: ubuntu-22.04 - distro: ubuntu
distro: ubuntu
version: "22.04" version: "22.04"
- target: ubuntu-23.10 - distro: ubuntu
distro: ubuntu
version: "23.10" version: "23.10"
- target: ubuntu-24.04 - distro: ubuntu
distro: ubuntu
version: "24.04" version: "24.04"
- target: debian-bullseye - distro: debian
distro: debian
version: bullseye version: bullseye
- target: debian-bookworm - distro: debian
distro: debian
version: bookworm version: bookworm
- target: debian-trixie - distro: debian
distro: debian
version: trixie version: trixie
steps: steps:
@ -122,36 +194,12 @@ jobs:
name: dangerzone.deb name: dangerzone.deb
path: "deb_dist/" path: "deb_dist/"
- name: Create end-user environment on (${{ matrix.target }}) - name: Build end-user environment
run: | run: |
./dev_scripts/env.py --distro ${{ matrix.distro }} \ ./dev_scripts/env.py --distro ${{ matrix.distro }} \
--version ${{ matrix.version }} \ --version ${{ matrix.version }} \
build build
- name: Configure Podman for Debian Bullseye specifically
if: matrix.target == 'debian-bullseye'
run: |
# Create a Podman config specifically for Bullseye (see #388).
mkdir bullseye_fix
cd bullseye_fix
cat > containers.conf <<EOF
[engine]
cgroup_manager="cgroupfs"
events_logger="file"
EOF
# Copy the Podman config into the container image we created for the
# Dangerzone environment.
cat > Dockerfile.bullseye <<EOF
FROM dangerzone.rocks/debian:bullseye-backports
RUN mkdir -p /home/user/.config/containers
COPY containers.conf /home/user/.config/containers/
EOF
# Create a new image from the Dangerzone environment and re-tag it.
podman build -t dangerzone.rocks/debian:bullseye-backports \
-f Dockerfile.bullseye .
- name: Run a test command - name: Run a test command
run: | run: |
./dev_scripts/env.py --distro ${{ matrix.distro }} \ ./dev_scripts/env.py --distro ${{ matrix.distro }} \
@ -165,31 +213,39 @@ jobs:
run dangerzone --help run dangerzone --help
build-install-rpm: build-install-rpm:
name: "Build and install a Dangerzone RPM on Fedora ${{matrix.version}}" name: "build-install-rpm (${{ matrix.distro }} ${{matrix.version}})"
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build-container-image
strategy: strategy:
matrix: matrix:
include: distro: ["fedora"]
- version: "39" version: ["39", "40"]
- version: "40"
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Build dev environment - name: Login to GHCR
run: | run: |
./dev_scripts/env.py --distro fedora --version ${{ matrix.version }} \ echo ${{ github.token }} | podman login ghcr.io -u USERNAME --password-stdin
build-dev
- name: Build Dangerzone image - name: Get the dev environment
run: | run: |
./dev_scripts/env.py --distro fedora --version ${{ matrix.version }} \ ./dev_scripts/env.py \
run --dev --no-gui \ --distro ${{ matrix.distro }} \
bash -c 'cd /home/user/dangerzone && python3 ./install/common/build-image.py' --version ${{ matrix.version }} \
build-dev --sync
- name: Restore container cache
uses: actions/cache@v4
with:
key: v2-${{ hashFiles('Dockerfile', 'dangerzone/conversion/common.py', 'dangerzone/conversion/doc_to_pixels.py', 'dangerzone/conversion/pixels_to_pdf.py') }}
path: |-
share/container.tar.gz
share/image-id.txt
- name: Build Dangerzone .rpm - name: Build Dangerzone .rpm
run: | run: |
./dev_scripts/env.py --distro fedora --version ${{ matrix.version }} \ ./dev_scripts/env.py --distro ${{ matrix.distro }} --version ${{ matrix.version }} \
run --dev --no-gui ./dangerzone/install/linux/build-rpm.py run --dev --no-gui ./dangerzone/install/linux/build-rpm.py
# Reclaim some space in this step, now that the dev environment is no # Reclaim some space in this step, now that the dev environment is no
@ -200,15 +256,82 @@ jobs:
- name: Build end-user environment - name: Build end-user environment
run: | run: |
./dev_scripts/env.py --distro fedora --version ${{ matrix.version }} \ ./dev_scripts/env.py --distro ${{ matrix.distro }} \
--version ${{ matrix.version }} \
build --download-pyside6 build --download-pyside6
- name: Run a test command - name: Run a test command
run: | run: |
./dev_scripts/env.py --distro fedora --version ${{ matrix.version }} \ ./dev_scripts/env.py --distro ${{ matrix.distro }} --version ${{ matrix.version }} \
run dangerzone-cli dangerzone/tests/test_docs/sample-pdf.pdf run dangerzone-cli dangerzone/tests/test_docs/sample-pdf.pdf
- name: Check that the Dangerzone GUI imports work - name: Check that the Dangerzone GUI imports work
run: | run: |
./dev_scripts/env.py --distro fedora --version ${{ matrix.version }} \ ./dev_scripts/env.py --distro ${{ matrix.distro }} --version ${{ matrix.version }} \
run dangerzone --help 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: "20.04"
- distro: ubuntu
version: "22.04"
- distro: ubuntu
version: "23.10"
- distro: ubuntu
version: "24.04"
- distro: debian
version: bullseye
- distro: debian
version: bookworm
- distro: debian
version: trixie
- distro: fedora
version: "39"
- distro: fedora
version: "40"
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.10"
- 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: Restore container cache
uses: actions/cache@v4
with:
key: v2-${{ hashFiles('Dockerfile', 'dangerzone/conversion/common.py', 'dangerzone/conversion/doc_to_pixels.py', 'dangerzone/conversion/pixels_to_pdf.py') }}
path: |-
share/container.tar.gz
share/image-id.txt
- name: Setup xvfb (Linux)
run: |
# 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: |-
./dev_scripts/env.py --distro ${{ matrix.distro }} --version ${{ matrix.version }} run --dev \
bash -c 'cd dangerzone; poetry run make test'

View file

@ -0,0 +1,3 @@
[engine]
cgroup_manager="cgroupfs"
events_logger="file"

View file

@ -1,12 +1,14 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse import argparse
import hashlib
import os import os
import pathlib import pathlib
import shutil import shutil
import subprocess import subprocess
import sys import sys
import urllib.request import urllib.request
from datetime import date
DEFAULT_GUI = True DEFAULT_GUI = True
DEFAULT_USER = "user" DEFAULT_USER = "user"
@ -55,8 +57,9 @@ will download it from:
# FIXME: Maybe create an enum for these values. # FIXME: Maybe create an enum for these values.
DISTROS = ["debian", "fedora", "ubuntu"] DISTROS = ["debian", "fedora", "ubuntu"]
CONTAINER_RUNTIMES = ["podman", "docker"] CONTAINER_RUNTIMES = ["podman", "docker"]
IMAGE_NAME_BUILD_DEV_FMT = "dangerzone.rocks/build/{distro}:{version}" IMAGES_REGISTRY = "ghcr.io/freedomofpress/"
IMAGE_NAME_BUILD_FMT = "dangerzone.rocks/{distro}:{version}" IMAGE_NAME_BUILD_DEV_FMT = "v2/dangerzone/build-dev/{distro}-{version}:{hash}"
IMAGE_NAME_BUILD_ENDUSER_FMT = "v2/dangerzone/end-user/{distro}-{version}:{hash}"
EPILOG = """\ EPILOG = """\
Examples: Examples:
@ -288,14 +291,29 @@ def distro_build(distro, version):
return distro_root(distro, version) / "build" return distro_root(distro, version) / "build"
def image_name_build(distro, version): def image_name_build_dev(distro, version):
"""Get the container image for the dev variant of a Dangerzone environment.""" """Get the container image for the dev variant of a Dangerzone environment."""
return IMAGE_NAME_BUILD_DEV_FMT.format(distro=distro, version=version) hash = hash_files(
get_files_in("dev_scripts")
+ [
git_root() / "pyproject.toml",
git_root() / "poetry.lock",
],
include_current_date=True,
)
return IMAGE_NAME_BUILD_DEV_FMT.format(distro=distro, version=version, hash=hash)
def image_name_install(distro, version): def image_name_build_enduser(distro, version):
"""Get the container image for the Dangerzone environment.""" """Get the container image for the Dangerzone end-user environment."""
return IMAGE_NAME_BUILD_FMT.format(distro=distro, version=version)
hash = hash_files(
get_files_in("install/linux", "debian"), include_current_date=True
)
return IMAGE_NAME_BUILD_ENDUSER_FMT.format(
distro=distro, version=version, hash=hash
)
def dz_version(): def dz_version():
@ -304,6 +322,34 @@ def dz_version():
return f.read().strip() return f.read().strip()
def hash_files(
file_paths: list[pathlib.Path], include_current_date: bool = False
) -> str:
"""Returns the hash value of a list of files using the sha256 hashing algorithm.
If specified, also adds the current date in the hash.
"""
hash_obj = hashlib.new("sha256")
for path in file_paths:
with open(path, "rb") as file:
file_data = file.read()
hash_obj.update(file_data)
if include_current_date:
current_date = date.today().strftime("%Y-%m-%d")
hash_obj.update(current_date.encode())
return hash_obj.hexdigest()
def get_files_in(*folders: list[str]) -> list[pathlib.Path]:
"""Return the list of all files present in the given folders"""
files = []
for folder in folders:
files.extend([p for p in (git_root() / folder).glob("**") if p.is_file()])
return files
class PySide6Manager: class PySide6Manager:
"""Provision PySide6 RPMs in our Dangerzone environments. """Provision PySide6 RPMs in our Dangerzone environments.
@ -512,13 +558,13 @@ class Env:
run_cmd += [ run_cmd += [
"--hostname", "--hostname",
"dangerzone-dev", "dangerzone-dev",
image_name_build(self.distro, self.version), image_name_build_dev(self.distro, self.version),
] ]
else: else:
run_cmd += [ run_cmd += [
"--hostname", "--hostname",
"dangerzone", "dangerzone",
image_name_install(self.distro, self.version), image_name_build_enduser(self.distro, self.version),
] ]
run_cmd += cmd run_cmd += cmd
@ -534,8 +580,26 @@ class Env:
(dist_state / ".bash_history").touch(exist_ok=True) (dist_state / ".bash_history").touch(exist_ok=True)
self.runtime_run(*run_cmd) self.runtime_run(*run_cmd)
def build_dev(self, show_dockerfile=DEFAULT_SHOW_DOCKERFILE): def pull_image_from_registry(self, image):
process = subprocess.run(self.runtime_cmd + ["pull", IMAGES_REGISTRY + image])
return process.returncode == 0
def push_image_to_registry(self, image):
process = subprocess.run(
self.runtime_cmd + ["push", image, IMAGES_REGISTRY + image]
)
return process.returncode == 0
def build_dev(self, show_dockerfile=DEFAULT_SHOW_DOCKERFILE, sync=False):
"""Build a Linux environment and install tools for Dangerzone development.""" """Build a Linux environment and install tools for Dangerzone development."""
image = image_name_build_dev(self.distro, self.version)
if sync and self.pull_image_from_registry(image):
# The image has been pulled from the registry, no need to build it.
return
elif sync:
print("Image label not in registry, building it")
if self.distro == "fedora": if self.distro == "fedora":
install_deps = DOCKERFILE_BUILD_DEV_FEDORA_DEPS install_deps = DOCKERFILE_BUILD_DEV_FEDORA_DEPS
else: else:
@ -588,6 +652,7 @@ class Env:
shutil.copy(git_root() / "pyproject.toml", build_dir) shutil.copy(git_root() / "pyproject.toml", build_dir)
shutil.copy(git_root() / "poetry.lock", build_dir) shutil.copy(git_root() / "poetry.lock", build_dir)
shutil.copy(git_root() / "dev_scripts" / "storage.conf", build_dir) shutil.copy(git_root() / "dev_scripts" / "storage.conf", build_dir)
shutil.copy(git_root() / "dev_scripts" / "containers.conf", build_dir)
if self.distro == "ubuntu" and self.version in ("22.04", "jammy"): if self.distro == "ubuntu" and self.version in ("22.04", "jammy"):
shutil.copy(git_root() / "dev_scripts" / "apt-tools-prod.pref", build_dir) shutil.copy(git_root() / "dev_scripts" / "apt-tools-prod.pref", build_dir)
shutil.copy( shutil.copy(
@ -596,9 +661,12 @@ class Env:
with open(build_dir / "Dockerfile", mode="w") as f: with open(build_dir / "Dockerfile", mode="w") as f:
f.write(dockerfile) f.write(dockerfile)
image = image_name_build(self.distro, self.version)
self.runtime_run("build", "-t", image, build_dir) self.runtime_run("build", "-t", image, build_dir)
if sync:
if not self.push_image_to_registry(image):
print("An error occured while trying to push to the container registry")
def build( def build(
self, self,
show_dockerfile=DEFAULT_SHOW_DOCKERFILE, show_dockerfile=DEFAULT_SHOW_DOCKERFILE,
@ -671,6 +739,7 @@ class Env:
# Populate the build context. # Populate the build context.
shutil.copy(package_src, package_dst) shutil.copy(package_src, package_dst)
shutil.copy(git_root() / "dev_scripts" / "storage.conf", build_dir) shutil.copy(git_root() / "dev_scripts" / "storage.conf", build_dir)
shutil.copy(git_root() / "dev_scripts" / "containers.conf", build_dir)
if self.distro == "ubuntu" and self.version in ("22.04", "jammy"): if self.distro == "ubuntu" and self.version in ("22.04", "jammy"):
shutil.copy(git_root() / "dev_scripts" / "apt-tools-prod.pref", build_dir) shutil.copy(git_root() / "dev_scripts" / "apt-tools-prod.pref", build_dir)
shutil.copy( shutil.copy(
@ -679,7 +748,7 @@ class Env:
with open(build_dir / "Dockerfile", mode="w") as f: with open(build_dir / "Dockerfile", mode="w") as f:
f.write(dockerfile) f.write(dockerfile)
image = image_name_install(self.distro, self.version) image = image_name_build_enduser(self.distro, self.version)
self.runtime_run("build", "-t", image, build_dir) self.runtime_run("build", "-t", image, build_dir)
@ -698,7 +767,7 @@ def env_run(args):
def env_build_dev(args): def env_build_dev(args):
"""Invoke the 'build-dev' command based on the CLI args.""" """Invoke the 'build-dev' command based on the CLI args."""
env = Env.from_args(args) env = Env.from_args(args)
return env.build_dev(show_dockerfile=args.show_dockerfile) return env.build_dev(show_dockerfile=args.show_dockerfile, sync=args.sync)
def env_build(args): def env_build(args):
@ -784,6 +853,12 @@ def parse_args():
action="store_true", action="store_true",
help="Do not build, only show the Dockerfile", help="Do not build, only show the Dockerfile",
) )
parser_build_dev.add_argument(
"--sync",
default=False,
action="store_true",
help="Attempt to pull the image, build it if not found and push it to the container registry",
)
# Build a development variant of a Dangerzone environment. # Build a development variant of a Dangerzone environment.
parser_build = subparsers.add_parser( parser_build = subparsers.add_parser(