--- title: "Creating a robust, zero-config SFTP testing environment on different platforms" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{SFTP-testing-envs} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- # Technical Summary ## 1. Project Objective To build an automated testing suite for the `sftpR` package that functions seamlessly across three distinct environments without manual configuration or security interruptions. ## 2. The Core Challenges ### A. SSH Security Handshakes (The "Interactive" Problem) * **Host Key Fingerprints:** Docker containers generate new SSH keys on every start. Standard clients detect this change and abort the connection to prevent "Man-in-the-Middle" attacks. * **Prompt Hanging:** In CI/CD (GitHub Actions/`act`), there is no terminal user to type "yes" to the "Trust this host?" prompt, causing tests to time out or crash. ### B. Network Architecture Conflicts (The "Port" Problem) * **Local/Cloud VM:** The R process runs *outside* the Docker engine. It must use **Port Mapping** (`127.0.0.1:2222` or `2223`) to reach the container. * **`act` (Local CI):** The R process runs *inside* a container on the same Docker network. It sees the SFTP container as a "neighbor" and must use the **Internal IP/Port** (`sftp:22`). * **Port Clashing:** Using port `2222` for both local dev and CI tests causes failures if a local container is already active. --- ## 3. Implemented Solutions ### Layer 1: R6 Class "Blindfold" (Security Bypass) Modified the R handle initialization to bypass strict SSH checks. * **`ssh_knownhosts = NULL`**: Instructs `libcurl` to ignore the system `known_hosts` file. * **`ssl_verifyhost = 0`**: Prevents connection drops if the IP/Host doesn't match the certificate/key exactly. ### Layer 2: Environment-Aware Routing (`helper-sftp.R`) Implemented a logic gate that detects the runner environment and selects the correct connection string: * **`act` Logic:** Connects to `sftp` on **Port 22**. * **Cloud Logic:** Connects to `127.0.0.1` on **Port 2223**. * **Local Logic:** Connects to `127.0.0.1` on **Port 2222**. ### Layer 3: Dynamic Infrastructure (`R-CMD-check.yaml`) * **Isolation:** Shifted the CI port to `2223` to prevent interference with local dev. * **DNS Injection:** Used `docker inspect` to grab the internal IP and added it to `/etc/hosts` as `sftp`. * **Network Discovery:** Added logic to identify the specific Docker network name used by `act` to ensure containers can "see" each other. --- ## 4. Modified Files & Impact | File | Change | Impact | | :--- | :--- | :--- | | **`R/sftp_connection.R`** | Added bypass options to `curl` handle. | Eliminates "Host Key not OK" errors and interactive prompts. | | **`tests/testthat/helper-sftp.R`** | Created `get_conn_info()`. | Switches between Internal (22) and External (2223) ports automatically. | | **`.github/workflows/R-CMD-check.yaml`** | Reordered steps and added network/IP exports. | Ensures the SFTP server is ready and reachable before R tests begin. |