Skip to content

Add Windows CI support with Swift 6.3 and swift-jinja migration - #63

Closed
alexey1312 wants to merge 1 commit into
mainfrom
fix/windows-ci-support
Closed

Add Windows CI support with Swift 6.3 and swift-jinja migration#63
alexey1312 wants to merge 1 commit into
mainfrom
fix/windows-ci-support

Conversation

@alexey1312

Copy link
Copy Markdown
Collaborator

Description

  • Add Windows build support across CI and release workflows using Swift 6.3 (development snapshot) with compnerd/gha-setup-swift
  • Replace Stencil template engine with swift-jinja for cross-platform compatibility (PathKit dependency didn't support Windows)
  • Make XcodeProj conditional (#if !os(Windows)) since it depends on Apple-only frameworks
  • Wrap XcodeProjectWriter usage in #if canImport(XcodeProj) across 6 export files
  • Use idiomatic #if canImport(FoundationNetworking) instead of #if os(Linux) for all non-Apple platform imports
  • Resolve swift-resvg Windows artifactbundle linking (resvg.lib naming for lld-link)
  • Add JinjaSupport shared module for Jinja2 template rendering across all export modules
  • Integrate Windows build job into ci.yml and release.yml, remove standalone windows-test.yml
  • Update platform documentation (CLAUDE.md, linux-compat.md, README.md)

Additional notes

  • Windows CI runs build-only (no tests yet) — Debug and Release configurations
  • Swift 6.3 required on Windows due to SPM artifactbundle handling (no lib prefix for .lib files)
  • swift-resvg pinned to exact: "0.45.1-swift.15" which includes Windows pre-built binary
  • Release workflow produces exfig-windows-x64.zip archive with ExFig.exe and resource bundles

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @alexey1312, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly expands the project's platform compatibility by introducing full Windows support, including dedicated CI/CD workflows. A major refactoring involved migrating from the Stencil templating engine to Jinja2, which was crucial for achieving cross-platform functionality. The changes also include robust conditional compilation to manage platform-specific dependencies and improved URL handling for enhanced security and reliability.

Highlights

  • Windows CI Support: Added comprehensive support for building and testing on Windows within the CI/CD pipelines, utilizing Swift 6.3 development snapshots and compnerd/gha-setup-swift.
  • Jinja2 Template Engine Migration: Replaced the Stencil template engine with swift-jinja across all export modules to improve cross-platform compatibility, particularly for Windows where PathKit (a Stencil dependency) was not supported.
  • Conditional Compilation for Platform-Specific Code: Implemented conditional compilation (#if !os(Windows) and #if canImport(...)) for XcodeProj dependencies and FoundationNetworking/FoundationXML imports, ensuring the codebase adapts correctly to different operating systems.
  • New JinjaSupport Module: Introduced a new shared module, JinjaSupport, to centralize Jinja2 template rendering helpers and facilitate the migration from Stencil.
  • Swift-resvg Windows Compatibility: Resolved issues with swift-resvg artifactbundle linking on Windows by addressing lld-link naming conventions and leveraging Swift 6.3's improved .lib file handling.
  • Path Traversal Sanitization: Enhanced security by adding path sanitization to FileContents.Destination.url to prevent directory traversal vulnerabilities.
Changelog
  • .claude/rules/linux-compat.md
    • Updated documentation to include Windows compatibility details and platform-specific features.
  • .swiftlint.yml
    • Added Sources/ExFigCLI/Resources/webConfig.swift to the list of excluded files.
  • CLAUDE.md
    • Updated project context to reflect the switch to Jinja2 templates and the addition of Windows support.
    • Increased the module count from twelve to thirteen and added JinjaSupport to the architecture overview.
    • Updated dependency table to list swift-jinja and specify swift-resvg version for Windows compatibility.
    • Updated troubleshooting section to reference Jinja2 template errors.
  • CONFIG.md
    • Updated descriptions for templatesPath fields in iOS, Android, Flutter, and Web configurations from Stencil to Jinja2.
  • Package.resolved
    • Updated package dependencies, removing Komondor, PackageConfig, ShellOut, Stencil, and StencilSwiftKit.
    • Added swift-jinja and updated versions for swift-resvg and swift-yyjson.
  • Package.swift
    • Refactored package dependencies into conditional arrays to support platform-specific requirements.
    • Removed Stencil and StencilSwiftKit dependencies and added swift-jinja.
    • Introduced a new target JinjaSupport for shared Jinja template rendering utilities.
    • Updated swift-resvg dependency to a specific exact version for Windows compatibility.
    • Wrapped XcodeProj dependency and ExFigCLI target dependencies in #if !os(Windows) blocks.
  • README.md
    • Updated requirements to include Swift 6.3+ for Windows and explicitly list Windows as a supported platform.
    • Changed the customizable code templates feature from Stencil to Jinja2.
  • Sources/AndroidExport/AndroidCodeConnectExporter.swift
    • Removed Stencil import.
    • Updated template rendering to use JinjaTemplateRenderer and .jinja templates.
  • Sources/AndroidExport/AndroidColorExporter.swift
    • Removed PathKit and Stencil imports.
    • Updated template rendering to use JinjaTemplateRenderer and .jinja templates.
  • Sources/AndroidExport/AndroidComposeIconExporter.swift
    • Removed Stencil import.
    • Updated template rendering to use JinjaTemplateRenderer and .jinja templates.
  • Sources/AndroidExport/AndroidExporter.swift
    • Replaced PathKit, Stencil, and StencilSwiftKit imports with JinjaSupport.
    • Refactored template environment creation to use JinjaTemplateRenderer methods.
  • Sources/AndroidExport/AndroidTypographyExporter.swift
    • Removed Stencil import.
    • Updated template rendering to use JinjaTemplateRenderer and .jinja templates.
  • Sources/AndroidExport/CLAUDE.md
    • Updated class hierarchy and template system descriptions to reflect the switch from Stencil to Jinja2.
    • Updated instructions for adding new exporters and modifying templates to reference Jinja.
  • Sources/AndroidExport/Resources/CodeConnect.figma.kt.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/AndroidExport/Resources/Colors.kt.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/AndroidExport/Resources/Icons.kt.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/AndroidExport/Resources/Typography.kt.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/AndroidExport/Resources/colors.xml.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/AndroidExport/Resources/header.jinja
    • Renamed from .stencil to .jinja.
  • Sources/AndroidExport/Resources/typography.xml.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/ExFig-Android/CLAUDE.md
    • Updated module role and configuration descriptions to reference Jinja2 templates instead of Stencil.
  • Sources/ExFig-Flutter/CLAUDE.md
    • Updated module role and dependencies descriptions to reference Jinja2 templates instead of Stencil.
  • Sources/ExFig-Web/CLAUDE.md
    • Updated configuration description to reference Jinja2 templates instead of Stencil.
  • Sources/ExFig-iOS/CLAUDE.md
    • Updated module overview and configuration descriptions to reference Jinja2 templates instead of Stencil.
  • Sources/ExFigCLI/ExFig.docc/CustomTemplates.md
    • Updated documentation to reflect the migration from Stencil to Jinja2 for custom templates, including syntax examples and best practices.
  • Sources/ExFigCLI/ExFig.docc/Development.md
    • Updated documentation to state that templates use Jinja2 syntax.
  • Sources/ExFigCLI/ExFig.docc/Flutter/Flutter.md
    • Updated templatesPath description to refer to custom Jinja2 templates.
  • Sources/ExFigCLI/Output/FileDownloader.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
    • Added validateDownloadURL function to ensure HTTPS scheme and valid host, and integrated it into the download process.
  • Sources/ExFigCLI/Output/FileWriter.swift
    • Changed conditional import for FoundationXML from #if os(Linux) to #if canImport(FoundationXML).
  • Sources/ExFigCLI/Output/XcodeProjectWriter.swift
    • Wrapped the entire XcodeProjectWriter class definition in #if canImport(XcodeProj) to make it conditional on XcodeProj availability.
  • Sources/ExFigCLI/Pipeline/SharedDownloadQueue.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
    • Integrated validateDownloadURL to ensure download URLs are secure and valid.
  • Sources/ExFigCLI/Subcommands/Export/PluginColorsExport.swift
    • Wrapped Xcode project update logic in #if canImport(XcodeProj) to handle cases where XcodeProj is not available.
  • Sources/ExFigCLI/Subcommands/Export/PluginIconsExport.swift
    • Wrapped Xcode project update logic in #if canImport(XcodeProj).
  • Sources/ExFigCLI/Subcommands/Export/PluginImagesExport.swift
    • Wrapped Xcode project update logic in #if canImport(XcodeProj).
  • Sources/ExFigCLI/Subcommands/Export/PluginTypographyExport.swift
    • Wrapped Xcode project update logic in #if canImport(XcodeProj).
  • Sources/ExFigCLI/Subcommands/Export/iOSColorsExport.swift
    • Wrapped Xcode project update logic in #if canImport(XcodeProj).
  • Sources/ExFigConfig/PKL/PKLEvaluator.swift
    • Added allowedModules and allowedResources options to PklSwift.withEvaluator to restrict network imports and reads, enhancing security.
  • Sources/ExFigCore/FileContents.swift
    • Implemented path sanitization in Destination.url to remove .. and . components, preventing path traversal vulnerabilities.
  • Sources/FigmaAPI/Client.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
    • Introduced RedirectGuardDelegate to strip sensitive authentication headers during cross-host or scheme-downgrading HTTP redirects.
  • Sources/FigmaAPI/Endpoint/BaseEndpoint.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
  • Sources/FigmaAPI/Endpoint/ComponentsEndpoint.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
  • Sources/FigmaAPI/Endpoint/Endpoint.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
    • Updated makeRequest protocol requirement to throws.
  • Sources/FigmaAPI/Endpoint/FileMetadataEndpoint.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
    • Updated makeRequest to throw URLError instead of fatalError for invalid URL components.
  • Sources/FigmaAPI/Endpoint/ImageEndpoint.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
    • Updated makeRequest to throw URLError instead of fatalError for invalid URL components.
  • Sources/FigmaAPI/Endpoint/LatestReleaseEndpoint.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
  • Sources/FigmaAPI/Endpoint/NodesEndpoint.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
    • Updated makeRequest to throw URLError instead of fatalError for invalid URL components.
  • Sources/FigmaAPI/Endpoint/StylesEndpoint.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
  • Sources/FigmaAPI/Endpoint/UpdateVariablesEndpoint.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
    • Removed force_try and made JSONCodec.encode a throwing call in makeRequest.
  • Sources/FigmaAPI/Endpoint/VariablesEndpoint.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
  • Sources/FigmaAPI/FigmaAPIError.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
  • Sources/FigmaAPI/FigmaClient.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
  • Sources/FigmaAPI/GitHubClient.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
  • Sources/FigmaAPI/RateLimitedClient.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
  • Sources/FigmaAPI/RetryPolicy.swift
    • Changed conditional import for FoundationNetworking from #if os(Linux) to #if canImport(FoundationNetworking).
  • Sources/FlutterExport/CLAUDE.md
    • Updated module role and dependencies descriptions to reflect the switch from Stencil to Jinja2.
    • Updated instructions for changing template output and adding new exporters to reference Jinja.
  • Sources/FlutterExport/FlutterColorExporter.swift
    • Removed Stencil import.
    • Updated template rendering to use JinjaTemplateRenderer and .jinja templates.
  • Sources/FlutterExport/FlutterExporter.swift
    • Replaced PathKit, Stencil, and StencilSwiftKit imports with JinjaSupport.
    • Refactored template environment creation to use JinjaTemplateRenderer methods.
  • Sources/FlutterExport/FlutterIconsExporter.swift
    • Removed Stencil import.
    • Updated template rendering to use JinjaTemplateRenderer and .jinja templates.
  • Sources/FlutterExport/FlutterImagesExporter.swift
    • Removed Stencil import.
    • Updated template rendering to use JinjaTemplateRenderer and .jinja templates.
  • Sources/FlutterExport/Resources/colors.dart.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/FlutterExport/Resources/header.jinja
    • Renamed from .stencil to .jinja.
  • Sources/FlutterExport/Resources/icons.dart.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/FlutterExport/Resources/images.dart.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/JinjaSupport/JinjaTemplateRenderer.swift
    • Added new file JinjaTemplateRenderer.swift to provide core Jinja template loading and rendering functionality.
  • Sources/JinjaSupport/TemplateLoadError.swift
    • Added new file TemplateLoadError.swift to define custom errors for Jinja template loading.
  • Sources/SVGKit/SVGParser.swift
    • Changed conditional import for FoundationXML from #if os(Linux) to #if canImport(FoundationXML).
  • Sources/WebExport/CLAUDE.md
    • Updated architecture and template system descriptions to reflect the switch from Stencil to Jinja2.
  • Sources/WebExport/Resources/Icon.tsx.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/WebExport/Resources/IconIndex.ts.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/WebExport/Resources/Image.tsx.jinja
    • Renamed from .stencil to .jinja and updated template include syntax, adjusted JSX attribute syntax for Jinja compatibility.
  • Sources/WebExport/Resources/ImageIndex.ts.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/WebExport/Resources/header.jinja
    • Renamed from .stencil to .jinja.
  • Sources/WebExport/Resources/theme.css.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/WebExport/Resources/theme.json.jinja
    • Renamed from .stencil to .jinja and updated template include syntax, adjusted Jinja loop syntax from forloop.last to loop.last.
  • Sources/WebExport/Resources/types.ts.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/WebExport/Resources/variables.ts.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/WebExport/WebColorExporter.swift
    • Removed Stencil import.
    • Updated template rendering to use JinjaTemplateRenderer and .jinja templates.
  • Sources/WebExport/WebExporter.swift
    • Replaced PathKit, Stencil, and StencilSwiftKit imports with JinjaSupport.
    • Refactored template environment creation to use JinjaTemplateRenderer methods.
  • Sources/WebExport/WebIconsExporter.swift
    • Removed Stencil import.
    • Updated template rendering to use JinjaTemplateRenderer and .jinja templates, pre-loading Icon.tsx.jinja template source.
  • Sources/WebExport/WebImagesExporter.swift
    • Removed Stencil import.
    • Updated template rendering to use JinjaTemplateRenderer and .jinja templates, pre-loading Image.tsx.jinja template source.
  • Sources/XcodeExport/CLAUDE.md
    • Updated class hierarchy and template system descriptions to reflect the switch from Stencil to Jinja2.
    • Updated instructions for adding template context variables to reference Jinja.
  • Sources/XcodeExport/Resources/Bundle+extension.swift.jinja.include
    • Renamed from .stencil.include to .jinja.include and updated Jinja loop syntax.
  • Sources/XcodeExport/Resources/CodeConnect.figma.swift.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/XcodeExport/Resources/Color+extension.swift.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/XcodeExport/Resources/Font+extension.swift.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/XcodeExport/Resources/Image+extension.swift.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/XcodeExport/Resources/Image+extension.swift.jinja.include
    • Renamed from .stencil.include to .jinja.include.
  • Sources/XcodeExport/Resources/Label.swift.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/XcodeExport/Resources/LabelStyle+extension.swift.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/XcodeExport/Resources/LabelStyle.swift.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/XcodeExport/Resources/UIColor+extension.swift.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/XcodeExport/Resources/UIFont+extension.swift.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/XcodeExport/Resources/UIImage+extension.swift.jinja
    • Renamed from .stencil to .jinja and updated template include syntax.
  • Sources/XcodeExport/Resources/UIImage+extension.swift.jinja.include
    • Renamed from .stencil.include to .jinja.include.
  • Sources/XcodeExport/Resources/header.jinja
    • Renamed from .stencil to .jinja.
  • Sources/XcodeExport/XcodeColorExporter.swift
    • Removed PathKit and Stencil imports.
    • Updated template rendering to use JinjaTemplateRenderer and .jinja templates, including a new contextWithHeaderAndBundle helper.
  • Sources/XcodeExport/XcodeExporterBase.swift
    • Replaced PathKit, Stencil, and StencilSwiftKit imports with JinjaSupport.
    • Refactored template environment creation to use JinjaTemplateRenderer methods and added contextWithHeaderAndBundle helper.
  • Sources/XcodeExport/XcodeImagesExporterBase.swift
    • Updated template names from .stencil to .jinja.
    • Modified template context handling to use contextWithHeaderAndBundle for full templates and conditional header inclusion for partials.
  • Sources/XcodeExport/XcodeTypographyExporter.swift
    • Removed Stencil import.
    • Updated template rendering to use JinjaTemplateRenderer and .jinja templates.
  • Tests/ExFigCoreTests/FileContentsTests.swift
    • Added new test cases to verify path traversal sanitization in Destination.url.
  • Tests/ExFigTests/Helpers/MockClient.swift
    • Updated endpoint.makeRequest call to try.
  • Tests/FigmaAPITests/EndpointMakeRequestTests.swift
    • Added new test file EndpointMakeRequestTests.swift to verify that endpoint makeRequest methods correctly throw errors for invalid URLs.
  • Tests/FigmaAPITests/FileMetadataEndpointTests.swift
    • Updated endpoint.makeRequest call to try.
  • Tests/FigmaAPITests/ImageEndpointTests.swift
    • Updated endpoint.makeRequest call to try.
  • Tests/FigmaAPITests/Mocks/MockClient.swift
    • Updated endpoint.makeRequest call to try.
  • Tests/FigmaAPITests/NodesEndpointTests.swift
    • Updated endpoint.makeRequest call to try.
  • Tests/FigmaAPITests/RedirectGuardDelegateTests.swift
    • Added new test file RedirectGuardDelegateTests.swift to verify the behavior of the RedirectGuardDelegate in stripping sensitive headers during redirects.
  • Tests/FigmaAPITests/UpdateVariablesEndpointTests.swift
    • Updated endpoint.makeRequest call to try.
  • Tests/WebExportTests/WebColorExporterTests.swift
    • Added tests to validate JSON output structure and ensure correct handling of light-only color exports.
  • Tests/WebExportTests/WebIconsExporterTests.swift
    • Added a test to verify the content and structure of generated icon components.
  • Tests/WebExportTests/WebImagesExporterTests.swift
    • Added a test to verify the content and Jinja brace escaping in generated image components.
  • openspec/project.md
    • Updated the project overview to list swift-jinja as the template engine.
  • openspec/specs/web-export/spec.md
    • Updated the web export specification to refer to Jinja2 templates for custom template scenarios.
Ignored Files
  • Ignored by pattern: .github/workflows/** (3)
    • .github/workflows/ci.yml
    • .github/workflows/release.yml
    • .github/workflows/windows-test.yml
Activity
  • Added Windows build support across CI and release workflows using Swift 6.3 (development snapshot) with compnerd/gha-setup-swift.
  • Replaced Stencil template engine with swift-jinja for cross-platform compatibility.
  • Made XcodeProj conditional (#if !os(Windows)) as it depends on Apple-only frameworks.
  • Wrapped XcodeProjectWriter usage in #if canImport(XcodeProj) across 6 export files.
  • Used idiomatic #if canImport(FoundationNetworking) instead of #if os(Linux) for all non-Apple platform imports.
  • Resolved swift-resvg Windows artifactbundle linking issues (resvg.lib naming for lld-link).
  • Added JinjaSupport shared module for Jinja2 template rendering across all export modules.
  • Integrated Windows build job into ci.yml and release.yml, removing standalone windows-test.yml.
  • Updated platform documentation (CLAUDE.md, linux-compat.md, README.md).
  • Noted that Windows CI runs build-only (no tests yet) for Debug and Release configurations.
  • Highlighted that Swift 6.3 is required on Windows due to SPM artifactbundle handling.
  • Pinned swift-resvg to exact: "0.45.1-swift.15" which includes a Windows pre-built binary.
  • Confirmed that the release workflow produces exfig-windows-x64.zip archive with ExFig.exe and resource bundles.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces significant improvements by adding Windows CI support and migrating the templating engine from Stencil to swift-jinja for better cross-platform compatibility. The changes are extensive and well-executed, including conditional compilation for platform-specific dependencies like XcodeProj and modernizing platform checks with #if canImport. I've identified a critical security vulnerability in the new path traversal sanitization logic that needs to be addressed. Additionally, the PR includes several other commendable security enhancements, such as preventing network access during PKL evaluation and stripping authentication tokens on cross-host redirects, which greatly improve the tool's robustness.

Comment on lines +18 to +21
if sanitized.isEmpty {
assertionFailure("Destination path is empty after sanitization (original: \(relativePath))")
return directory.appendingPathComponent(relativePath)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-critical critical

This fallback logic re-introduces the path traversal vulnerability that the sanitization is meant to prevent. If sanitized is empty (e.g., if relativePath is "../"), this code will fall back to using the original, unsafe relativePath. In a release build, the assertionFailure will be ignored, and the code will silently write a file outside the intended directory.

To fix this, you should throw an error if the sanitized path is empty, ensuring that no unsafe file operations can occur.

        if sanitized.isEmpty {
            throw URLError(.badURL, userInfo: [NSLocalizedDescriptionKey: "Invalid destination path after sanitization (original: \(relativePath))"])
        }

- Add Windows build to ci.yml and release.yml using Swift 6.3
- Replace Stencil with swift-jinja for cross-platform compatibility
- Add JinjaSupport shared module for template rendering
- Make XcodeProj conditional (#if !os(Windows)) in Package.swift
- Wrap XcodeProjectWriter in #if canImport(XcodeProj) (6 export files)
- Use #if canImport(FoundationNetworking) instead of #if os(Linux)
- Pin swift-resvg to 0.45.1-swift.15 (Windows artifactbundle)
- Delete standalone windows-test.yml
- Update docs: CLAUDE.md, linux-compat.md, README.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@alexey1312
alexey1312 force-pushed the fix/windows-ci-support branch from f87fec7 to 55b01ae Compare February 24, 2026 04:41
@alexey1312 alexey1312 closed this Feb 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant