From e300964879cda780ef27c27585ab2516bf6cc3d0 Mon Sep 17 00:00:00 2001 From: Ashwin Maroli Date: Fri, 6 Sep 2024 11:40:02 +0530 Subject: [PATCH] Windows CI on GitHub Actions (#9659) Merge pull request 9659 --- .github/CODEOWNERS | 2 -- .github/workflows/ci.yml | 25 +++++++++--------- README.markdown | 3 +-- appveyor.yml | 49 ------------------------------------ features/collections.feature | 20 +++++++-------- features/step_definitions.rb | 16 ++++++------ features/support/helpers.rb | 7 ++++++ test/helper.rb | 31 +++++++++++++++++++++++ 8 files changed, 70 insertions(+), 83 deletions(-) delete mode 100644 appveyor.yml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a6f9434c..3077f286 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -65,8 +65,6 @@ # @jekyll/stability Gemfile @jekyll/stability *.gemspec @jekyll/stability -.travis.yml @jekyll/stability -appveyor.yml @jekyll/stability /lib/jekyll/configuration.rb @jekyll/stability /lib/jekyll/deprecator.rb @jekyll/stability /lib/jekyll/frontmatter_defaults.rb @jekyll/stability diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8ca6ee66..138ab088 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,27 +12,28 @@ on: jobs: ci: - name: "Run Tests (${{ matrix.label }})" - runs-on: "ubuntu-latest" + name: "Run Tests (${{ matrix.ruby.label }} on ${{ matrix.os.label }})" + runs-on: ${{ matrix.os.image }} strategy: fail-fast: false matrix: - include: + ruby: - label: Ruby 2.7 - ruby_version: "2.7" - - label: Ruby 3.0 - ruby_version: "3.0" - - label: Ruby 3.1 - ruby_version: "3.1" - - label: Ruby 3.2 - ruby_version: "3.2" + version: "2.7" + - label: Ruby 3.3 + version: "3.3" + os: + - label: Linux + image: "ubuntu-latest" + - label: Windows + image: "windows-latest" steps: - name: Checkout Repository uses: actions/checkout@v4 - - name: "Set up ${{ matrix.label }}" + - name: "Set up ${{ matrix.ruby.label }}" uses: ruby/setup-ruby@v1 with: - ruby-version: ${{ matrix.ruby_version }} + ruby-version: ${{ matrix.ruby.version }} bundler-cache: true - name: Run Minitest based tests run: bash script/test diff --git a/README.markdown b/README.markdown index ad55a2f3..81b30328 100644 --- a/README.markdown +++ b/README.markdown @@ -1,8 +1,7 @@ # [Jekyll](https://jekyllrb.com/) [![Gem Version](https://img.shields.io/gem/v/jekyll.svg)][ruby-gems] -[![Linux Build Status](https://github.com/jekyll/jekyll/workflows/Continuous%20Integration/badge.svg)][ci-workflow] -[![Windows Build status](https://img.shields.io/appveyor/ci/jekyll/jekyll/master.svg?label=Windows%20build)][appveyor] +[![Build Status](https://github.com/jekyll/jekyll/workflows/Continuous%20Integration/badge.svg)][ci-workflow] [![Backers on Open Collective](https://opencollective.com/jekyll/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/jekyll/sponsors/badge.svg)](#sponsors) diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index d37c277b..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,49 +0,0 @@ -version: "{build}" -image: Visual Studio 2019 -build: off - -clone_depth: 5 - -branches: - only: - - master - - themes - - /.*-stable$/ - -environment: - BUNDLE_WITHOUT: "benchmark:development" - matrix: - - RUBY_FOLDER_VER: "27" - TZINFO_VERSION: "~> 1.2" - TEST_SUITE: "test" - - RUBY_FOLDER_VER: "27" - TZINFO_VERSION: "~> 2.0" - TEST_SUITE: "test" - - RUBY_FOLDER_VER: "27" - TEST_SUITE: "default-site" - - RUBY_FOLDER_VER: "27" - TEST_SUITE: "profile-docs" - - RUBY_FOLDER_VER: "27" - TEST_SUITE: "memprof" - - RUBY_FOLDER_VER: "27" - TZINFO_VERSION: "~> 1.2" - TEST_SUITE: "cucumber" - - RUBY_FOLDER_VER: "27" - TZINFO_VERSION: "~> 2.0" - TEST_SUITE: "cucumber" - -install: - - SET PATH=C:\Ruby%RUBY_FOLDER_VER%-x64\bin;%PATH% - - bundle config set --local clean 'true' - - bundle config set --local path 'vendor\bundle' - - bundle install --retry 5 --jobs=%NUMBER_OF_PROCESSORS% - -test_script: - - ruby --version - - gem --version - - bundler --version - - bash ./script/cibuild - -cache: - # If one of the files after the right arrow changes, cache will be invalidated - - 'vendor\bundle -> appveyor.yml,Gemfile,jekyll.gemspec' diff --git a/features/collections.feature b/features/collections.feature index 8b8813b6..8e3f482b 100644 --- a/features/collections.feature +++ b/features/collections.feature @@ -82,8 +82,8 @@ Feature: Collections When I run jekyll build Then I should get a zero exit status Then the _site directory should exist - And I should see "Collections: _methods/3940394-21-9393050-fifif1323-test.md _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/trailing-dots...md _methods/um_hi.md" in "_site/index.html" unless Windows - And I should see "Collections: _methods/3940394-21-9393050-fifif1323-test.md _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/trailing-dots...md _methods/yaml_with_dots.md" in "_site/index.html" if on Windows + And I should see "Collections: _methods/3940394-21-9393050-fifif1323-test.md _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/trailing-dots...md _methods/um_hi.md" in "_site/index.html" if platform supports symlinks + And I should see "Collections: _methods/3940394-21-9393050-fifif1323-test.md _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/trailing-dots...md _methods/yaml_with_dots.md" in "_site/index.html" if platform does not support symlinks Scenario: Collections specified as an hash Given I have an "index.html" page that contains "Collections: {% for method in site.methods %}{{ method.relative_path }} {% endfor %}" @@ -96,8 +96,8 @@ Feature: Collections When I run jekyll build Then I should get a zero exit status Then the _site directory should exist - And I should see "Collections: _methods/3940394-21-9393050-fifif1323-test.md _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/trailing-dots...md _methods/um_hi.md" in "_site/index.html" unless Windows - And I should see "Collections: _methods/3940394-21-9393050-fifif1323-test.md _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/trailing-dots...md _methods/yaml_with_dots.md" in "_site/index.html" if on Windows + And I should see "Collections: _methods/3940394-21-9393050-fifif1323-test.md _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/trailing-dots...md _methods/um_hi.md" in "_site/index.html" if platform supports symlinks + And I should see "Collections: _methods/3940394-21-9393050-fifif1323-test.md _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/trailing-dots...md _methods/yaml_with_dots.md" in "_site/index.html" if platform does not support symlinks Scenario: Rendered collection with document with future date Given I have a _puppies directory @@ -377,8 +377,8 @@ Feature: Collections When I run jekyll build Then I should get a zero exit status Then the _site directory should exist - And I should see "All documents: _methods/3940394-21-9393050-fifif1323-test.md _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/trailing-dots...md _methods/um_hi.md" in "_site/index.html" unless Windows - And I should see "All documents: _methods/3940394-21-9393050-fifif1323-test.md _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/trailing-dots...md _methods/yaml_with_dots.md" in "_site/index.html" if on Windows + And I should see "All documents: _methods/3940394-21-9393050-fifif1323-test.md _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/trailing-dots...md _methods/um_hi.md" in "_site/index.html" if platform supports symlinks + And I should see "All documents: _methods/3940394-21-9393050-fifif1323-test.md _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/trailing-dots...md _methods/yaml_with_dots.md" in "_site/index.html" if platform does not support symlinks Scenario: Documents have an output attribute, which is the converted HTML Given I have an "index.html" page that contains "Second document's output: {{ site.documents[2].output }}" @@ -432,8 +432,8 @@ Feature: Collections When I run jekyll build Then I should get a zero exit status And the _site directory should exist - And I should see "2. of 10:

Page without title.

" in "_site/index.html" unless Windows - And I should see "2. of 9:

Page without title.

" in "_site/index.html" if on Windows + And I should see "2. of 10:

Page without title.

" in "_site/index.html" if platform supports symlinks + And I should see "2. of 9:

Page without title.

" in "_site/index.html" if platform does not support symlinks Scenario: Sort by relative_path Given I have an "index.html" page that contains "Collections: {% assign methods = site.methods | sort: 'relative_path' %}{{ methods | map:"title" | join: ", " }}" @@ -446,8 +446,8 @@ Feature: Collections When I run jekyll build Then I should get a zero exit status Then the _site directory should exist - And I should see "Collections: this is a test!, Collection#entries, Jekyll.configuration, Jekyll.escape, Jekyll.sanitized_path, Site#generate, Initialize, Ellipsis Path, Site#generate, YAML with Dots" in "_site/index.html" unless Windows - And I should see "Collections: this is a test!, Collection#entries, Jekyll.configuration, Jekyll.escape, Jekyll.sanitized_path, Site#generate, Initialize, Ellipsis Path, YAML with Dots" in "_site/index.html" if on Windows + And I should see "Collections: this is a test!, Collection#entries, Jekyll.configuration, Jekyll.escape, Jekyll.sanitized_path, Site#generate, Initialize, Ellipsis Path, Site#generate, YAML with Dots" in "_site/index.html" if platform supports symlinks + And I should see "Collections: this is a test!, Collection#entries, Jekyll.configuration, Jekyll.escape, Jekyll.sanitized_path, Site#generate, Initialize, Ellipsis Path, YAML with Dots" in "_site/index.html" if platform does not support symlinks Scenario: Sort all entries by a Front Matter key defined in all entries Given I have an "index.html" page that contains "Collections: {{ site.tutorials | map: 'title' | join: ', ' }}" diff --git a/features/step_definitions.rb b/features/step_definitions.rb index 616ab0b6..b8c0e35b 100644 --- a/features/step_definitions.rb +++ b/features/step_definitions.rb @@ -287,28 +287,28 @@ end # -Then(%r!^I should (not )?see "(.*)" in "(.*)" if on Windows$!) do |negative, text, file| +Then(%r!^I should (not )?see "(.*)" in "(.*)" if platform does not support symlinks$!) do |negative, text, file| step %(the "#{file}" file should exist) regexp = Regexp.new(text, Regexp::MULTILINE) if negative.nil? || negative.empty? - if Jekyll::Utils::Platforms.really_windows? - expect(file_contents(file)).to match regexp - else + if Platform.supports_symlink? expect(file_contents(file)).not_to match regexp + else + expect(file_contents(file)).to match regexp end end end # -Then(%r!^I should (not )?see "(.*)" in "(.*)" unless Windows$!) do |negative, text, file| +Then(%r!^I should (not )?see "(.*)" in "(.*)" if platform supports symlinks$!) do |negative, text, file| step %(the "#{file}" file should exist) regexp = Regexp.new(text, Regexp::MULTILINE) if negative.nil? || negative.empty? - if Jekyll::Utils::Platforms.really_windows? - expect(file_contents(file)).not_to match regexp - else + if Platform.supports_symlink? expect(file_contents(file)).to match regexp + else + expect(file_contents(file)).not_to match regexp end end end diff --git a/features/support/helpers.rb b/features/support/helpers.rb index b6e77eec..66e690af 100644 --- a/features/support/helpers.rb +++ b/features/support/helpers.rb @@ -18,6 +18,13 @@ class Paths def self.source_dir; SOURCE_DIR; end end +class Platform + REF_FILE = File.expand_path("../../test/source/symlink-test/symlinked-file", __dir__) + + def self.supports_symlink?; File.symlink?(REF_FILE); end +end + + # def file_content_from_hash(input_hash) diff --git a/test/helper.rb b/test/helper.rb index 37258e46..f6b1f925 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -93,6 +93,37 @@ module DirectoryHelpers end end +module Jekyll + # + # --- NOTE: --- + # + # This monkey-patch was introduced because GitHub Actions on Windows acknowledges symlinked test + # file `test/source/symlink-test/symlinked-file-outside-source` but errors out since the linked + # location `/etc/passwd` does not exist on Windows. + # + # --- TODO: --- + # + # Consider having the `symlinked-file-outside-source` point to a file that is outside the + # `source_dir` (defaults to `test/source`) yet is certain to exist on tested platforms. + # For example, `jekyll.gemspec` is a good candidate. + # + # This monkey-patch will then no longer be necessary. + # + class ModifiedReader < Reader + def read_directories(dir = "") + if dir.start_with?("/symlink") && Utils::Platforms.really_windows? + Jekyll.logger.debug "Skipping:", "Jekyll does not support symlinks on Windows" + else + super + end + end + end + + Hooks.register :site, :after_init do |site| + site.instance_variable_set(:@reader, ModifiedReader.new(site)) + end +end + class JekyllUnitTest < Minitest::Test include ::RSpec::Mocks::ExampleMethods include DirectoryHelpers