## Comprehensive self-test for update-torbrowser's signature-freshness
## cache logic. Exercises every cache state transition the bug-fix series
## on the downstream branch introduced (fresh install, cache hit,
## cross-context fallback, rejected tampered cache, rejected out-of-bounds
## cache, rejected invalid signature) and every wrapper (update-torbrowser,
## update-mullvadbrowser, update-i2pbrowser).
##
## Runs in a Debian trixie container. genmkfile, helper-scripts, and
## msgcollector are installed from their upstream Kicksecure git repositories
## using the project's own genmkfile install flow. No deb.kicksecure.com apt
## repo is added.

name: self-test

on:
  push:
    branches: [master]
  pull_request:
    branches: [master]
  workflow_dispatch:

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  self-test:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    container:
      image: debian:trixie
    steps:
      - name: Install apt pre-reqs + genmkfile + helper-scripts
        uses: org-ai-assisted/developer-meta-files/.github/actions/install-deps@master
        with:
          ## dctrl-tools provides grep-dctrl, which genmkfile uses to
          ## compute build dependencies from each package's
          ## debian/control.
          apt-packages: ca-certificates curl git sudo adduser build-essential dctrl-tools

      - name: Install msgcollector
        env:
          GH_REPOSITORY_OWNER: ${{ github.repository_owner }}
        run: |
          ## Clone msgcollector from the same org as the workflow.
          ## Resolves to org-ai-assisted/msgcollector on org-ai-assisted runs,
          ## Kicksecure/msgcollector on Kicksecure runs, etc. Hard error if the
          ## org does not have msgcollector - no implicit upstream fallback (an
          ## org choosing to host its own CI must explicitly fork msgcollector;
          ## a silent cross-org clone would be a supply-chain footgun).
          git clone --depth=1 \
              "https://github.com/${GH_REPOSITORY_OWNER}/msgcollector.git" \
              /tmp/msgcollector
          cd /tmp/msgcollector
          sudo genmkfile install

      - name: Install tb-updater runtime dependencies from Debian
        run: |
          set -eux
          export DEBIAN_FRONTEND=noninteractive
          ## faketime is used by make-fixture --signed-at for the
          ## "signature too old" negative scenario.
          ## acl provides setfacl, which sandbox-update-torbrowser
          ## requires at script-load time ('has setfacl').
          apt-get install -y --no-install-recommends \
            sq sqop libarchive-tools safe-rm \
            curl jq psmisc pv iproute2 python3 \
            faketime acl

      - name: Checkout tb-updater
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6.0.2
        with:
          persist-credentials: false

      - name: Install tb-updater from checkout
        run: |
          set -eux
          sudo genmkfile install

      - name: Create an unprivileged test account
        run: |
          set -eux
          adduser --disabled-password --gecos '' tbtest
          ## The test scripts live in the repo checkout. tbtest needs to
          ## be able to reach them through the working tree.
          repo_path="$(pwd)"
          while [ "$repo_path" != "/" ]; do
            chmod o+rx "$repo_path"
            repo_path="$(dirname -- "$repo_path")"
          done
          chown -R tbtest:tbtest .github/ci

      - name: Smoke-test make-fixture
        run: |
          set -eux
          sudo -u tbtest env CI=true .github/ci/make-fixture /tmp/smoke-fix
          sudo -u tbtest sqop verify \
            /tmp/smoke-fix/99.0.0/tor-browser-linux-x86_64-99.0.0.tar.xz.asc \
            /tmp/smoke-fix/test-key.asc \
            < /tmp/smoke-fix/99.0.0/tor-browser-linux-x86_64-99.0.0.tar.xz

      - name: Run self-test (all scenarios)
        run: |
          sudo -u tbtest env CI=true .github/ci/self-test -v

      - name: Create tb-updater system user (mirrors tb-updater postinst)
        ## genmkfile install copies files but does not execute the
        ## package postinst, so the 'tb-updater' system account and its
        ## /var/lib/tb-updater/work home directory do not exist by
        ## default. sandbox-update-torbrowser hard-requires both. The
        ## adduser command below is taken verbatim from
        ## debian/tb-updater.postinst's create_tb_updater_user_account.
        ##
        ## TODO: Maybe instead, change how we install tb-updater so
        ## that the postinst is run? That way we keep a single source
        ## of truth for this.
        run: |
          set -eux
          adduser --home /var/lib/tb-updater/work --quiet --system --group tb-updater || true
          id tb-updater
          test -d /var/lib/tb-updater/work

      - name: Run sandbox-resume regression test
        ## sandbox-update-torbrowser is the postinst entry point and
        ## must run as root, so this scenario does not go through the
        ## unprivileged 'tbtest' account that the file://-fixture
        ## tests use.
        run: |
          env CI=true .github/ci/test-sandbox-resume

      - name: Show generated caches on failure
        if: failure()
        run: |
          set +e
          find /tmp/tb-selftest.* 2>/dev/null | head -80 || true
          find /var/lib/tb-updater/work -maxdepth 4 2>/dev/null || true
          find /var/lib/tb-updater/resume-stash -maxdepth 3 2>/dev/null || true
          ls -la /tmp/test-sandbox-resume-result 2>/dev/null || true
