rustd-resolved 0.2.1

A compatibility-oriented reimplementation of systemd-resolved
name: Replacement boot and rollback proof
run-name: Replacement boot and rollback proof ${{ inputs.source_sha || github.sha }}

on:
  push:
    branches:
      - main
    paths:
      - .github/workflows/replacement-boot-proof.yml
      - scripts/run-boot-replacement-vm.sh
      - src/**
      - nss/**
      - compat/upstream-systemd/**
      - Cargo.toml
      - Cargo.lock
      - build.rs
  workflow_dispatch:
    inputs:
      source_sha:
        description: Full Git commit to prove; blank selects the dispatch ref
        required: false
        type: string

permissions:
  contents: read
  statuses: write

jobs:
  prove:
    runs-on: ubuntu-24.04
    timeout-minutes: 90
    steps:
      - name: Check out exact source
        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
        with:
          ref: ${{ inputs.source_sha || github.sha }}
          fetch-depth: 1

      - name: Verify exact source identity
        shell: bash
        env:
          REQUESTED_SHA: ${{ inputs.source_sha || github.sha }}
        run: |
          set -euo pipefail
          [[ $REQUESTED_SHA =~ ^[0-9a-f]{40}$ ]]
          test "$(git rev-parse HEAD)" = "$REQUESTED_SHA"

      - name: Install build and QEMU dependencies
        shell: bash
        run: |
          set -euo pipefail
          sudo apt-get update
          sudo apt-get install --yes --no-install-recommends \
            debootstrap \
            gfortran \
            git \
            libssl-dev \
            liburing-dev \
            mtools \
            ovmf \
            python3-pefile \
            qemu-system-x86 \
            qemu-utils \
            systemd-boot
          git clone --filter=blob:none --no-checkout \
            https://github.com/systemd/mkosi.git "$RUNNER_TEMP/mkosi"
          git -C "$RUNNER_TEMP/mkosi" fetch --depth 1 origin \
            60ed8c964f8d98aa4b325f381c4b3bc6de91a0b7
          git -C "$RUNNER_TEMP/mkosi" checkout --detach \
            60ed8c964f8d98aa4b325f381c4b3bc6de91a0b7
          echo "$RUNNER_TEMP/mkosi/bin" >> "$GITHUB_PATH"
          rustup toolchain install 1.74.0 --profile minimal --component rustfmt,clippy
          rustup default 1.74.0
          rustc --version --verbose
          cargo --version --verbose

      - name: Verify pinned upstream baseline
        run: bash scripts/verify-upstream-resolved-baseline.sh

      - name: Build release candidate
        run: bash scripts/build-reproducible-release.sh

      - name: Boot candidate twice and verify rollback
        shell: bash
        run: |
          set -euo pipefail
          export PATH="$HOME/.local/bin:$PATH"
          bash scripts/run-boot-replacement-vm.sh \
            --binary target/reproducible-release/systemd-resolved \
            --client target/reproducible-release/resolvectl \
            --nss-module target/reproducible-release/libnss_resolve.so.2 \
            --output target/boot-replacement-vm

      - name: Write bound boot proof
        shell: bash
        run: |
          set -euo pipefail
          mkdir -p proof
          cp target/boot-replacement-vm/mkosi-build.log proof/
          cp target/boot-replacement-vm/qemu-console.log proof/
          cp target/boot-replacement-vm/evidence.json proof/
          python3 scripts/write-replacement-proof.py \
            --gate boot-replacement \
            --result pass \
            --output proof/boot-replacement.json \
            --artifact proof/mkosi-build.log \
            --artifact proof/qemu-console.log \
            --artifact proof/evidence.json \
            --metadata environment=qemu \
            --metadata boot-count=2 \
            --metadata rollback-verified=true \
            --summary 'The candidate daemon, client, and NSS module survived two QEMU boots and the distro resolver rollback was healthy.'

      - name: Upload bound boot proof
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: replacement-boot-proof-${{ inputs.source_sha || github.sha }}
          path: proof
          if-no-files-found: error
          retention-days: 30

      - name: Upload boot failure evidence
        if: ${{ failure() }}
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: replacement-boot-failure-${{ inputs.source_sha || github.sha }}
          path: target/boot-replacement-vm
          if-no-files-found: ignore
          retention-days: 14

  report:
    name: Publish boot proof status
    if: ${{ always() }}
    needs:
      - prove
    runs-on: ubuntu-24.04
    steps:
      - name: Publish exact-source status
        env:
          GH_TOKEN: ${{ github.token }}
          SOURCE_SHA: ${{ inputs.source_sha || github.sha }}
          RESULT: ${{ needs.prove.result }}
        run: |
          set -euo pipefail
          state=failure
          if [[ "$RESULT" == success ]]; then
            state=success
          fi
          payload=$(printf '{"state":"%s","context":"replacement/boot-proof","description":"Boot and rollback proof %s","target_url":"%s"}' "$state" "$state" "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}")
          curl --fail-with-body --silent --show-error -X POST \
            -H "Accept: application/vnd.github+json" \
            -H "Authorization: Bearer $GH_TOKEN" \
            -H "X-GitHub-Api-Version: 2022-11-28" \
            "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/statuses/${SOURCE_SHA}" \
            --data "$payload" >/dev/null