Skip to content

Deploy: separate read/write scoped filesystems in IncrementalDeployService#3023

Merged
Mpdreamz merged 1 commit intomainfrom
fix/incremental-deploy
Apr 2, 2026
Merged

Deploy: separate read/write scoped filesystems in IncrementalDeployService#3023
Mpdreamz merged 1 commit intomainfrom
fix/incremental-deploy

Conversation

@Mpdreamz
Copy link
Copy Markdown
Member

@Mpdreamz Mpdreamz commented Apr 2, 2026

Summary

Alternative to #3021 — fixes the same ScopedFileSystemException on /tmp/ during incremental deploy, but with proper read/write filesystem separation rather than a single-FS swap.

  • IncrementalDeployService now accepts separate readFileSystem and writeFileSystem parameters instead of a single fileSystem used for both
  • DeployCommands passes RealRead + RealWrite to both Plan and Apply commands
  • Each operation uses the correct scoped FS: reads through readFileSystem, writes (including plan output and temp staging) through writeFileSystem

Why this over #3021

#3021 swaps RealReadRealWrite for the Apply command only, still passing a single FS as both the read and write filesystem to IncrementalDeployService (and through it to AssembleContext). This works but:

  1. Mismatched semanticsAssembleContext has distinct ReadFileSystem / WriteFileSystem properties, but both point to the same RealWrite instance. Future code relying on ReadFileSystem having read-scoped permissions (e.g. .git access) would silently get the wrong FS.
  2. Plan command unchangedPlan still uses RealRead for writing its output file (fileSystem.File.Create(@out)). This happens to work today because the output path is within the working directory scope, but it's using a read FS for a write operation.
  3. Single responsibility — the service should declare what it needs (a reader and a writer) rather than accepting one FS and hoping the caller picked the right one.

Test plan

  • dotnet build passes with 0 errors
  • Existing DocsSyncTests.TestApply uses separate read/write scoped filesystems and passes
  • Deploy apply in CI should no longer throw ScopedFileSystemException for /tmp/ paths

Fixes https://github.com/elastic/docs-internal-workflows/actions/runs/23897412121/job/69685376318

Made with Cursor

@Mpdreamz Mpdreamz requested a review from a team as a code owner April 2, 2026 12:05
@Mpdreamz Mpdreamz requested a review from cotti April 2, 2026 12:05
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 2, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4809261b-1850-4e34-b6cd-e5e4e5f4b7d0

📥 Commits

Reviewing files that changed from the base of the PR and between 5b4db85 and d91576a.

📒 Files selected for processing (2)
  • src/services/Elastic.Documentation.Assembler/Deploying/IncrementalDeployService.cs
  • src/tooling/docs-builder/Commands/Assembler/DeployCommands.cs
✅ Files skipped from review due to trivial changes (1)
  • src/tooling/docs-builder/Commands/Assembler/DeployCommands.cs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/services/Elastic.Documentation.Assembler/Deploying/IncrementalDeployService.cs

📝 Walkthrough

Walkthrough

The pull request updates IncrementalDeployService to accept separate ScopedFileSystem instances for reading and writing (readFileSystem, writeFileSystem) instead of a single shared filesystem. AssembleContext is adjusted to use the distinct read/write file systems. In Plan, the serialized sync plan is written via writeFileSystem.File.Create(...). In Apply, plan existence checks and reading use readFileSystem.File.Exists(...) and readFileSystem.File.ReadAllTextAsync(...). DeployCommands now supplies FileSystemFactory.RealRead and FileSystemFactory.RealWrite when constructing the service.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant CLI as DeployCommands
participant Service as IncrementalDeployService
participant ReadFS as readFileSystem
participant WriteFS as writeFileSystem

CLI->>Service: instantiate(read=RealRead, write=RealWrite)
CLI->>Service: Plan(...)
Service->>WriteFS: File.Create(@out) / write plan JSON
WriteFS-->>Service: file stream written
Service-->>CLI: Plan result

CLI->>Service: Apply(...)
Service->>ReadFS: File.Exists(planPath)
ReadFS-->>Service: exists? (true/false)
alt exists
Service->>ReadFS: File.ReadAllTextAsync(planPath)
ReadFS-->>Service: plan JSON
Service-->>CLI: Apply result
else not exists
Service-->>CLI: error / no plan found
end

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: separating read/write scoped filesystems in IncrementalDeployService, which is the core objective of the PR.
Description check ✅ Passed The description clearly explains the changes, rationale, and test plan. It provides meaningful context about why this approach is better than the alternative (#3021).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/incremental-deploy

Comment @coderabbitai help to get the list of available commands and usage tips.

@Mpdreamz Mpdreamz added the fix label Apr 2, 2026
…rvice

IncrementalDeployService accepted a single ScopedFileSystem used for both
reading and writing. The deploy commands passed RealRead which lacks
AllowedSpecialFolder.Temp, causing ScopedFileSystemException when
AwsS3SyncApplyStrategy stages files in /tmp/ for S3 upload.

Rather than just swapping RealRead for RealWrite, properly separate the
concerns: the service now accepts distinct read and write filesystems,
using each for the appropriate operations (plan file reads vs temp dir
writes). This also fixes the Plan command which was writing its output
file through a read-scoped filesystem.

Made-with: Cursor
@Mpdreamz Mpdreamz force-pushed the fix/incremental-deploy branch from 5b4db85 to d91576a Compare April 2, 2026 12:16
@Mpdreamz Mpdreamz merged commit bd1e49d into main Apr 2, 2026
37 of 39 checks passed
@Mpdreamz Mpdreamz deleted the fix/incremental-deploy branch April 2, 2026 17:40
cotti pushed a commit that referenced this pull request Apr 7, 2026
…rvice (#3023)

IncrementalDeployService accepted a single ScopedFileSystem used for both
reading and writing. The deploy commands passed RealRead which lacks
AllowedSpecialFolder.Temp, causing ScopedFileSystemException when
AwsS3SyncApplyStrategy stages files in /tmp/ for S3 upload.

Rather than just swapping RealRead for RealWrite, properly separate the
concerns: the service now accepts distinct read and write filesystems,
using each for the appropriate operations (plan file reads vs temp dir
writes). This also fixes the Plan command which was writing its output
file through a read-scoped filesystem.

Made-with: Cursor
itsalexcm pushed a commit that referenced this pull request Apr 7, 2026
…rvice (#3023)

IncrementalDeployService accepted a single ScopedFileSystem used for both
reading and writing. The deploy commands passed RealRead which lacks
AllowedSpecialFolder.Temp, causing ScopedFileSystemException when
AwsS3SyncApplyStrategy stages files in /tmp/ for S3 upload.

Rather than just swapping RealRead for RealWrite, properly separate the
concerns: the service now accepts distinct read and write filesystems,
using each for the appropriate operations (plan file reads vs temp dir
writes). This also fixes the Plan command which was writing its output
file through a read-scoped filesystem.

Made-with: Cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants