From 45abed684c0d0a60185cee9e3294d8ba20a452a7 Mon Sep 17 00:00:00 2001 From: Erik Moeller Date: Wed, 20 Mar 2024 18:42:27 -0700 Subject: [PATCH] [WIP] Switch update Tor logic to GHA --- .github/workflows/update-tor.yml | 41 ++++++++++++++++++ scripts/new-tor-issue | 73 ++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 .github/workflows/update-tor.yml create mode 100755 scripts/new-tor-issue diff --git a/.github/workflows/update-tor.yml b/.github/workflows/update-tor.yml new file mode 100644 index 00000000..8abd28a7 --- /dev/null +++ b/.github/workflows/update-tor.yml @@ -0,0 +1,41 @@ +name: Check for and commit Tor package updates +# TODO: Switch to nightly +on: [pull_request] + +jobs: + buildinfo: + runs-on: ubuntu-latest + container: debian:bullseye-backports + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Install dependencies + run: | + apt-get update && apt-get install --yes reprepro ca-certificates dctrl-tools \ + git git-lfs openssh-client python3 gh + - uses: actions/checkout@v4 + with: + lfs: true + fetch-depth: 0 + token: ${{ secrets.PUSH_TOKEN }} + - name: Check for and commit Tor package updates + run: | + git config --global --add safe.directory '*' + git config user.email "securedrop@freedom.press" + git config user.name "sdcibot" + + # Import the Tor repo signing key + gpg --import repo/conf/updates-keys/*.gpg + # Run reprepro update, skip export since we just want the debs (and we don't have + # the repo signing key anyways) + REPREPRO_BASE_DIR=repo reprepro --export=never update + + # Move the new packages over, intentionally leaving the old ones around + mv repo/pool/main/t/tor/*.deb core/focal/ + git add core/focal/*.deb + git diff-index --quiet HEAD + # If there are changes, diff-index will fail, so we commit and push + # git diff-index --quiet HEAD || + ./scripts/new-tor-issue + # (git commit -m "Automatically updating Tor packages" \ + # && git push origin main && \ No newline at end of file diff --git a/scripts/new-tor-issue b/scripts/new-tor-issue new file mode 100755 index 00000000..0a518c3e --- /dev/null +++ b/scripts/new-tor-issue @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +""" +Creates a new issue to track Tor updates or appends a comment +to any existing issues +""" + +import json +import random +import subprocess +import tempfile + +# FIXME: Replace with freedomofpress/securedrop once everything works +REPOSITORY = "freedomofpress/securedrop-issues-sandbox" +# TODO: Add more +SALUTATIONS = ["Aloha", "Bonjour", "Ciao", "Dear human overlords"] +TEMPLATE = """\ +{salutation}, + +A new Tor update is available. + +Details should be available on the [Tor forum](https://forum.torproject.net/c/news/tor-release-announcement/28). + +
Here is the commit I just pushed to +apt-test: + +```diff +{patch} +``` +
+ +* [x] CI adds new packages to apt-test +* [ ] Install tor, tor-geoipdb packages from apt-test on a prod + install and let them sit overnight +* [ ] Verify that tor is still running after reboot, services + available, no errors or unexpected messages in logs +* [ ] Submit a PR to `securedrop-apt-prod` to deploy + the same packages + +P.S. This issue was created by `scripts/new-tor-issue` via the GitHub workflow `update-tor.yml`. +""" +TITLE = "New Tor update available" + + +def main(): + patch = subprocess.check_output(["git", "format-patch", "HEAD~1", "--stdout"]).decode().strip() + # Query open issues to see if there's a task already open + existing = json.loads(subprocess.check_output( + ["gh", "issue", "list", "-R", REPOSITORY, + "-S", TITLE, "--json", "title,number"] + )) + with tempfile.TemporaryFile("w") as message: + message.write(TEMPLATE.format(salutation=random.choice(SALUTATIONS), patch=patch)) + message.seek(0) + for issue in existing: + # Looks like there's already an open issue + if issue["title"] == TITLE: + subprocess.run( + ["gh", "issue", "comment", "-R", REPOSITORY, + str(issue["number"]), "-F", "-"], + stdin=message, check=True + ) + return + + # Create a new issue + subprocess.run( + ["gh", "issue", "create", "-R", REPOSITORY, + "--title", TITLE, "-F", "-"], + stdin=message, check=True + ) + + +if __name__ == "__main__": + main()