mirror of
https://github.com/freedomofpress/dangerzone.git
synced 2025-04-28 18:02:38 +02:00
WIP: Longer builds, more reproducible
This commit is contained in:
parent
da6a52bfbc
commit
1d8026e333
2 changed files with 91 additions and 84 deletions
142
.github/workflows/release-container-image.yaml
vendored
142
.github/workflows/release-container-image.yaml
vendored
|
@ -54,19 +54,19 @@ jobs:
|
||||||
- prepare
|
- prepare
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
#matrix:
|
||||||
platform:
|
# platform:
|
||||||
- suffix: ""
|
# - suffix: ""
|
||||||
name: "linux/amd64"
|
# name: "linux/amd64"
|
||||||
- suffix: "-arm"
|
# - suffix: "-arm"
|
||||||
name: "linux/arm64"
|
# name: "linux/arm64"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Prepare
|
#- name: Prepare
|
||||||
run: |
|
# run: |
|
||||||
platform=${{ matrix.platform.name }}
|
# platform=${{ matrix.platform.name }}
|
||||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
# echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Login to GHCR
|
- name: Login to GHCR
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
|
@ -80,7 +80,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
driver-opts: image=${{ env.BUILDKIT_IMAGE }}
|
driver-opts: image=${{ env.BUILDKIT_IMAGE }}
|
||||||
|
|
||||||
- name: Build and push by digest
|
- name: Build and push
|
||||||
id: build
|
id: build
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
|
@ -92,71 +92,71 @@ jobs:
|
||||||
# Remove potentially incorrect Docker provenance that cannot be
|
# Remove potentially incorrect Docker provenance that cannot be
|
||||||
# reproduced.
|
# reproduced.
|
||||||
provenance: false
|
provenance: false
|
||||||
platforms: ${{ matrix.platform.name }}
|
platforms: linux/amd64,linux/arm64
|
||||||
outputs: type=image,"name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}",rewrite-timestamp=true,push-by-digest=true,name-canonical=true,push=true
|
outputs: type=registry,"name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}",rewrite-timestamp=true,name-canonical=true
|
||||||
cache-from: type=gha
|
cache-from: type=gha
|
||||||
cache-to: type=gha,mode=max
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
- name: Export digest
|
#- name: Export digest
|
||||||
run: |
|
# run: |
|
||||||
mkdir -p ${{ runner.temp }}/digests
|
# mkdir -p ${{ runner.temp }}/digests
|
||||||
digest="${{ steps.build.outputs.digest }}"
|
# digest="${{ steps.build.outputs.digest }}"
|
||||||
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
# touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||||
echo "Image digest is: ${digest}"
|
# echo "Image digest is: ${digest}"
|
||||||
|
|
||||||
- name: Upload digest
|
#- name: Upload digest
|
||||||
uses: actions/upload-artifact@v4
|
# uses: actions/upload-artifact@v4
|
||||||
with:
|
# with:
|
||||||
name: digests-${{ env.PLATFORM_PAIR }}
|
# name: digests-${{ env.PLATFORM_PAIR }}
|
||||||
path: ${{ runner.temp }}/digests/*
|
# path: ${{ runner.temp }}/digests/*
|
||||||
if-no-files-found: error
|
# if-no-files-found: error
|
||||||
retention-days: 1
|
# retention-days: 1
|
||||||
|
|
||||||
merge:
|
#merge:
|
||||||
runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
needs:
|
# needs:
|
||||||
- prepare
|
# - prepare
|
||||||
- build
|
# - build
|
||||||
outputs:
|
# outputs:
|
||||||
digest: ${{ steps.image.outputs.digest }}
|
# digest: ${{ steps.image.outputs.digest }}
|
||||||
image: ${{ steps.image.outputs.image }}
|
# image: ${{ steps.image.outputs.image }}
|
||||||
steps:
|
# steps:
|
||||||
- uses: actions/checkout@v4
|
# - uses: actions/checkout@v4
|
||||||
with:
|
# with:
|
||||||
fetch-depth: 0
|
# fetch-depth: 0
|
||||||
|
|
||||||
- name: Compute image tag
|
# - name: Compute image tag
|
||||||
id: tag
|
# id: tag
|
||||||
run: |
|
# run: |
|
||||||
DEBIAN_ARCHIVE_DATE=${{ needs.prepare.outputs.debian_archive_date }}
|
# DEBIAN_ARCHIVE_DATE=${{ needs.prepare.outputs.debian_archive_date }}
|
||||||
TAG=$(git describe --long --first-parent | tail -c +2)
|
# TAG=$(git describe --long --first-parent | tail -c +2)
|
||||||
echo "tag=${DEBIAN_ARCHIVE_DATE}-${TAG}" >> $GITHUB_OUTPUT
|
# echo "tag=${DEBIAN_ARCHIVE_DATE}-${TAG}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Download digests
|
# - name: Download digests
|
||||||
uses: actions/download-artifact@v4
|
# uses: actions/download-artifact@v4
|
||||||
with:
|
# with:
|
||||||
path: ${{ runner.temp }}/digests
|
# path: ${{ runner.temp }}/digests
|
||||||
pattern: digests-*
|
# pattern: digests-*
|
||||||
merge-multiple: true
|
# merge-multiple: true
|
||||||
|
|
||||||
- name: Login to GHCR
|
# - name: Login to GHCR
|
||||||
uses: docker/login-action@v3
|
# uses: docker/login-action@v3
|
||||||
with:
|
# with:
|
||||||
registry: ghcr.io
|
# registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
# username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
# password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
# - name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
# uses: docker/setup-buildx-action@v3
|
||||||
with:
|
# with:
|
||||||
driver-opts: image=${{ env.BUILDKIT_IMAGE }}
|
# driver-opts: image=${{ env.BUILDKIT_IMAGE }}
|
||||||
|
|
||||||
- name: Create manifest list and push
|
# - name: Create manifest list and push
|
||||||
working-directory: ${{ runner.temp }}/digests
|
# working-directory: ${{ runner.temp }}/digests
|
||||||
run: |
|
# run: |
|
||||||
IMAGE=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.tag }}
|
# IMAGE=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.tag }}
|
||||||
DIGESTS=$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
|
# DIGESTS=$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
|
||||||
docker buildx imagetools create -t ${IMAGE} ${DIGESTS}
|
# docker buildx imagetools create -t ${IMAGE} ${DIGESTS}
|
||||||
|
|
||||||
- name: Inspect image
|
- name: Inspect image
|
||||||
id: image
|
id: image
|
||||||
|
@ -173,15 +173,15 @@ jobs:
|
||||||
# the container registry.
|
# the container registry.
|
||||||
provenance:
|
provenance:
|
||||||
needs:
|
needs:
|
||||||
- merge
|
- build
|
||||||
permissions:
|
permissions:
|
||||||
actions: read # for detecting the Github Actions environment.
|
actions: read # for detecting the Github Actions environment.
|
||||||
id-token: write # for creating OIDC tokens for signing.
|
id-token: write # for creating OIDC tokens for signing.
|
||||||
packages: write # for uploading attestations.
|
packages: write # for uploading attestations.
|
||||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0
|
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0
|
||||||
with:
|
with:
|
||||||
digest: ${{ needs.merge.outputs.digest }}
|
digest: ${{ needs.build.outputs.digest }}
|
||||||
image: ${{ needs.merge.outputs.image }}
|
image: ${{ needs.build.outputs.image }}
|
||||||
registry-username: ${{ github.actor }}
|
registry-username: ${{ github.actor }}
|
||||||
secrets:
|
secrets:
|
||||||
registry-password: ${{ secrets.GITHUB_TOKEN }}
|
registry-password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
@ -190,7 +190,7 @@ jobs:
|
||||||
check-reproducibility:
|
check-reproducibility:
|
||||||
needs:
|
needs:
|
||||||
- prepare
|
- prepare
|
||||||
- merge
|
- build
|
||||||
runs-on: ubuntu-24.04${{ matrix.platform.suffix }}
|
runs-on: ubuntu-24.04${{ matrix.platform.suffix }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
@ -209,5 +209,5 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
./dev_scripts/reproduce-image.py \
|
./dev_scripts/reproduce-image.py \
|
||||||
--debian-archive-date ${{ needs.build.prepare.debian_archive_date }} \
|
--debian-archive-date ${{ needs.build.prepare.debian_archive_date }} \
|
||||||
--source ${{ needs.merge.outputs.image }}@${{ needs.merge.outputs.digest }} \
|
--source ${{ needs.build.outputs.image }}@${{ needs.build.outputs.digest }} \
|
||||||
--platform ${{ matrix.platform.name }}
|
--platform ${{ matrix.platform.name }}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import argparse
|
||||||
import hashlib
|
import hashlib
|
||||||
import logging
|
import logging
|
||||||
import pathlib
|
import pathlib
|
||||||
|
import platform
|
||||||
import stat
|
import stat
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
@ -85,16 +86,20 @@ def diffoci_download():
|
||||||
DIFFOCI_PATH.chmod(DIFFOCI_PATH.stat().st_mode | stat.S_IEXEC)
|
DIFFOCI_PATH.chmod(DIFFOCI_PATH.stat().st_mode | stat.S_IEXEC)
|
||||||
|
|
||||||
|
|
||||||
def diffoci_diff(runtime, source, local_target, platform=None):
|
def diffoci_diff(runtime, source, target, platform=None):
|
||||||
"""Diff the source image against the recently built target image using diffoci."""
|
"""Diff the source image against the recently built target image using diffoci."""
|
||||||
target = f"{runtime}://{local_target}"
|
|
||||||
platform_args = [] if not platform else ["--platform", platform]
|
platform_args = [] if not platform else ["--platform", platform]
|
||||||
|
logger.info(f"Loading image tarball in diffoci")
|
||||||
|
with open("share/container.tar") as f:
|
||||||
|
subprocess.run([str(DIFFOCI_PATH), "load"], stdin=f, check=True)
|
||||||
|
logger.info(f"Performing a strict diff between the two images")
|
||||||
try:
|
try:
|
||||||
return run(
|
return run(
|
||||||
str(DIFFOCI_PATH),
|
str(DIFFOCI_PATH),
|
||||||
"diff",
|
"diff",
|
||||||
source,
|
source,
|
||||||
target,
|
target,
|
||||||
|
# "--semantic",
|
||||||
"--verbose",
|
"--verbose",
|
||||||
*platform_args,
|
*platform_args,
|
||||||
)
|
)
|
||||||
|
@ -116,17 +121,19 @@ def build_image(
|
||||||
platform_args = [] if not platform else ["--platform", platform]
|
platform_args = [] if not platform else ["--platform", platform]
|
||||||
runtime_args = [] if not runtime else ["--runtime", runtime]
|
runtime_args = [] if not runtime else ["--runtime", runtime]
|
||||||
date_args = [] if not date else ["--debian-archive-date", date]
|
date_args = [] if not date else ["--debian-archive-date", date]
|
||||||
run(
|
subprocess.run(
|
||||||
"python3",
|
[
|
||||||
"./install/common/build-image.py",
|
"python3",
|
||||||
"--no-save",
|
"./install/common/build-image.py",
|
||||||
"--use-cache",
|
"--use-cache",
|
||||||
str(use_cache),
|
str(use_cache),
|
||||||
*date_args,
|
*date_args,
|
||||||
*platform_args,
|
*platform_args,
|
||||||
*runtime_args,
|
*runtime_args,
|
||||||
"--tag",
|
"--tag",
|
||||||
tag,
|
tag,
|
||||||
|
],
|
||||||
|
check=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue