diff --git a/.gitattributes b/.gitattributes
index 1d0faa1..6e13592 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1,4 @@
*.deb filter=lfs diff=lfs merge=lfs -text
*.rpm filter=lfs diff=lfs merge=lfs -text
+*.gz filter=lfs diff=lfs merge=lfs -text
+*.bz2 filter=lfs diff=lfs merge=lfs -text
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 28b51f7..3baa5f4 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -23,3 +23,25 @@ jobs:
wget https://github.com/freedomofpress/securedrop-debian-packaging/raw/main/securedrop-keyring/securedrop-keyring.gpg
gpg --import securedrop-keyring.gpg && gpg --armor --export > securedrop-keyring.asc
./tools/check-signed securedrop-keyring.asc
+
+ metadata:
+ runs-on: ubuntu-latest
+ container: debian:bookworm
+ steps:
+ - name: Install dependencies
+ run: |
+ apt-get update && apt-get install --yes python3 git git-lfs createrepo-c
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ lfs: true
+ fetch-depth: 0
+ - name: Check repository metadata is up-to-date
+ run: |
+ git config --global --add safe.directory '*'
+ shopt -s globstar
+ # Parse the value out of
+ export SOURCE_DATE_EPOCH=$(grep -m 1 "revision" public/**/repomd.xml | cut -d '>' -f 2 | cut -d '<' -f 1)
+ ./tools/publish-real
+ git status
+ git diff --exit-code
diff --git a/tools/publish b/tools/publish
new file mode 100755
index 0000000..bb590ec
--- /dev/null
+++ b/tools/publish
@@ -0,0 +1,6 @@
+#!/bin/bash
+# Pull the latest image
+podman pull debian:bookworm
+# Mount the git repo to /srv, install necessary packages and run the publish script
+podman run --rm -it -v $(git rev-parse --show-toplevel):/srv:Z debian:bookworm \
+ bash -c "apt-get update && apt-get install -y python3 createrepo-c && /srv/tools/publish-real"
diff --git a/tools/publish-real b/tools/publish-real
new file mode 100755
index 0000000..f782d78
--- /dev/null
+++ b/tools/publish-real
@@ -0,0 +1,44 @@
+#!/usr/bin/env python3
+"""
+Script for generating yum repository metadata. Files are
+copied into public/ and metadata is generated there.
+"""
+import os
+import shutil
+import subprocess
+from pathlib import Path
+
+
+def main():
+ root = Path(__file__).parent.parent
+ public = root / "public"
+ workstation = root / "workstation"
+ # Reset public, copy the workstation/ tree into it
+ if public.exists():
+ shutil.rmtree(public)
+ public.mkdir()
+ shutil.copytree(workstation, public / "workstation")
+ # Folders are public/workstation/dom0/fXX, run createrepo_c in each one
+ for folder in public.glob("*/*/*/"):
+ if not folder.is_dir():
+ continue
+ print(f"Generating metadata for {folder}")
+ args = ["createrepo_c"]
+ if "SOURCE_DATE_EPOCH" in os.environ:
+ # The and fields are set to the current UNIX time
+ # unless we explicitly override them. In most cases we want to use
+ # the current time except when we're doing reproducibility testing.
+ args.extend(
+ [
+ "--revision",
+ os.environ["SOURCE_DATE_EPOCH"],
+ "--set-timestamp-to-revision",
+ ]
+ )
+ args.append(str(folder))
+ subprocess.check_call(args)
+ print("Done!")
+
+
+if __name__ == "__main__":
+ main()