## End-to-end dry-run smoke. Heavyweight (5-15 min). Invoked as a
## reusable workflow from run_automated_builder.yml so the build is
## gated on the dry-run passing in the same Actions UI run; also
## available as workflow_dispatch for ad-hoc manual smoke tests.
##
## See agents/github-actions-security.md for the standard
## permissions / persist-credentials / fork-PR / SHA-pin patterns.

name: Dry-run

on:
  workflow_call:
  workflow_dispatch:

permissions:
  contents: read

## Concurrency: per developer-meta-files' agents/github-actions.md
## G-A-006, github.workflow inside a reusable resolves to the
## caller's workflow name. local-test-build.yml calls this file
## via `uses: ./.github/workflows/local-build-dry-run.yml` and
## carries `${{ github.workflow }}-${{ github.ref }}` itself, so a
## bare same-key here would collide with the caller and trip the
## deadlock detector ("Canceling since a deadlock was detected for
## concurrency group: ..."). The trailing literal `-dry-run` is the
## differentiator the caller does not carry, matching the codeql
## reusable's `${{ inputs.language }}` pattern.
##
## This file is `local-` prefixed (repo-private, never propagated)
## but is also dispatchable standalone via workflow_dispatch for
## ad-hoc smoke tests. The same key works in both modes:
##   called via uses:   group = "00 Run automated builder-<ref>-dry-run"
##                       caller's group = "00 Run automated builder-<ref>"
##                       different keys -> no deadlock
##   workflow_dispatch  group = "Dry-run-<ref>-dry-run"
##                       unique per ref -> standard cancel-on-push
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}-dry-run
  cancel-in-progress: true

env:
  ## debian:trixie - Debian 13, current stable. TODO: forky.
  ## Re-pin procedure: agents/github-actions-security.md.
  DEBIAN_IMAGE: 'debian:trixie@sha256:35b8ff74ead4880f22090b617372daff0ccae742eb5674455d542bef71ef1999'

jobs:
  dry-run:
    name: derivative-maker --dry-run true
    runs-on: ubuntu-latest

    if: github.event.pull_request.head.repo.full_name == github.repository || github.event_name != 'pull_request'

    timeout-minutes: 25

    ## Subsequent steps run inside a privileged debian:trixie with
    ## systemd as PID 1 so 'systemctl start approx' (the build's apt
    ## cache) works. The host (ubuntu-latest) only hosts docker; a
    ## plain 'container:' block does not boot systemd inside. The
    ## launch-systemd-container composite action bakes the image and
    ## waits for systemd to become ready; subsequent steps
    ## docker-exec into the container with --workdir /workspace.
    steps:
      - name: Checkout repository (no submodules yet)
        ## submodules: false so the next steps can re-target each
        ## submodule's origin URL at the fork before init.
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6
        with:
          submodules: false
          fetch-depth: 0
          persist-credentials: false

      - name: Mirror Kicksecure/ and Whonix/ to ${{ github.repository_owner }}
        ## Must run BEFORE 'submodule update --init' so the rewrites
        ## are visible to the recursive clone.
        env:
          REPOSITORY_OWNER: ${{ github.repository_owner }}
        if: github.repository_owner != 'Whonix' && github.repository_owner != 'Kicksecure'
        run: ./ci/configure-fork-mirror "${REPOSITORY_OWNER}" "${REPOSITORY_OWNER}"

      - name: Initialize submodules
        run: git submodule update --init --recursive

      - name: Check out matching fork branch in cross-org submodules (if present)
        ## head_ref on a fork PR is attacker-named; route it through
        ## an env var rather than inlining (actionlint).
        if: github.repository_owner != 'Whonix' && github.repository_owner != 'Kicksecure'
        env:
          FORK_BRANCH: ${{ github.head_ref || github.ref_name }}
        run: ./ci/checkout-fork-submodule-branches "${FORK_BRANCH}"

      - name: Start systemd-enabled Debian container
        uses: org-ai-assisted/developer-meta-files/.github/actions/launch-systemd-container@master
        with:
          name: dryrun
          image: ${{ env.DEBIAN_IMAGE }}
          wait-seconds: '90'

      - name: Run dry-run inside container
        ## --workdir /workspace: the action mounts ${{ github.workspace }}
        ## at /workspace inside the container; the dry-run script is
        ## referenced via './ci/dry-run' and needs PWD to match.
        run: docker exec --env CI=true --workdir /workspace dryrun ./ci/dry-run

      - name: Tear down container
        if: always()
        run: docker rm --force dryrun || true

      - name: Reclaim workspace ownership
        if: always()
        ## The privileged dryrun container ran ./ci/dry-run as root,
        ## leaving root-owned files in the bind-mounted $GITHUB_WORKSPACE.
        ## The host runner can no longer mkdir into the workspace
        ## (e.g. for actions/checkout below) until ownership is
        ## restored. Passwordless sudo is available on ubuntu-latest
        ## hosted runners.
        run: sudo chown -R "$(id -u):$(id -g)" "${GITHUB_WORKSPACE}"

      - name: Checkout developer-meta-files (summary script)
        if: always()
        ## Needed for ci/step-summary-emit.sh. derivative-maker
        ## does not vendor a copy; checkout @master keeps the org's
        ## single source of truth. Pinned SHA matches the existing
        ## actions/checkout in this file.
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6
        with:
          repository: org-ai-assisted/developer-meta-files
          ref: master
          path: .dmf
          persist-credentials: false

      - name: Emit step summary
        if: always()
        ## Headline panel for the Actions tab: outcome + image used.
        ## Detailed build/teardown output stays in the per-step logs.
        ## Template values routed through env: per
        ## developer-meta-files#87 (avoid CodeQL inline-${{...}}-
        ## in-run: flag).
        env:
          JOB_STATUS: ${{ job.status }}
        run: |
          ./.dmf/ci/step-summary-emit.sh \
            --tool 'Dry-run' \
            --column-header field \
            --row "outcome=${JOB_STATUS}" \
            --row "image=${DEBIAN_IMAGE}"
