From a2159e80f594aba1a4658acb8b8b2e91480cb8f6 Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Mon, 29 Jul 2024 16:50:06 +0200 Subject: [PATCH] Add Windows CI (#14065) This PR changes the GitHub action workflow for V4 to start running all unit tests and build on both Ubuntu (our current default) _and_ Windows. This is to ensure we catch issues with paths and other Windows-specific things sooner. It does, however, not replace testing on Windows. --- .github/workflows/ci.yml | 10 +++++++--- crates/oxide/tests/auto_content.rs | 18 +++++++++++++----- .../src/utils/renderer.test.ts | 15 +++++++++++---- .../@tailwindcss-cli/src/utils/test-helpers.ts | 5 +++++ .../@tailwindcss-postcss/src/index.test.ts | 2 +- packages/tailwindcss/src/css-parser.bench.ts | 4 +++- 6 files changed, 40 insertions(+), 14 deletions(-) create mode 100644 packages/@tailwindcss-cli/src/utils/test-helpers.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c8a8ee2c0..35be5723a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,12 +11,14 @@ permissions: jobs: build: - runs-on: ubuntu-latest - timeout-minutes: 15 - strategy: + fail-fast: false matrix: node-version: [20] + runner: [ubuntu-latest, windows-latest] + + runs-on: ${{ matrix.runner }} + timeout-minutes: 15 steps: - uses: actions/checkout@v3 @@ -61,6 +63,8 @@ jobs: - name: Lint run: pnpm run lint + # Only lint on linux to avoind \r\n line ending errors + if: matrix.runner == 'ubuntu-latest' - name: Test run: pnpm run test diff --git a/crates/oxide/tests/auto_content.rs b/crates/oxide/tests/auto_content.rs index 2859a39cc..68fb809f9 100644 --- a/crates/oxide/tests/auto_content.rs +++ b/crates/oxide/tests/auto_content.rs @@ -1,7 +1,7 @@ #[cfg(test)] mod auto_content { - use std::fs; use std::process::Command; + use std::{fs, path}; use tailwindcss_oxide::*; use tempfile::tempdir; @@ -15,7 +15,8 @@ mod auto_content { // Create the necessary files for (path, contents) in paths_with_content { - let path = dir.join(path); + // Ensure we use the right path seperator for the current platform + let path = dir.join(path.replace("/", path::MAIN_SEPARATOR.to_string().as_str())); let parent = path.parent().unwrap(); if !parent.exists() { fs::create_dir_all(parent).unwrap(); @@ -38,18 +39,25 @@ mod auto_content { let mut paths: Vec<_> = result .files .into_iter() - .map(|x| x.replace(&format!("{}/", &base), "")) + .map(|x| x.replace(&format!("{}{}", &base, path::MAIN_SEPARATOR), "")) .collect(); for glob in result.globs { - paths.push(format!("{}/{}", glob.base, glob.glob)); + paths.push(format!( + "{}{}{}", + glob.base, + path::MAIN_SEPARATOR, + glob.glob + )); } paths = paths .into_iter() .map(|x| { - let parent_dir = format!("{}/", &base.to_string()); + let parent_dir = format!("{}{}", &base.to_string(), path::MAIN_SEPARATOR); x.replace(&parent_dir, "") + // Normalize paths to use unix style separators + .replace("\\", "/") }) .collect(); diff --git a/packages/@tailwindcss-cli/src/utils/renderer.test.ts b/packages/@tailwindcss-cli/src/utils/renderer.test.ts index d234be40f..0df4cde83 100644 --- a/packages/@tailwindcss-cli/src/utils/renderer.test.ts +++ b/packages/@tailwindcss-cli/src/utils/renderer.test.ts @@ -1,24 +1,31 @@ import path from 'path' import { describe, expect, it } from 'vitest' import { relative, wordWrap } from './renderer' +import { normalizeWindowsSeperators } from './test-helpers' describe('relative', () => { it('should print an absolute path relative to the current working directory', () => { - expect(relative(path.resolve('index.css'))).toMatchInlineSnapshot(`"./index.css"`) + expect(normalizeWindowsSeperators(relative(path.resolve('index.css')))).toMatchInlineSnapshot( + `"./index.css"`, + ) }) it('should prefer the shortest value by default', () => { // Shortest between absolute and relative paths - expect(relative('index.css')).toMatchInlineSnapshot(`"index.css"`) + expect(normalizeWindowsSeperators(relative('index.css'))).toMatchInlineSnapshot(`"index.css"`) }) it('should be possible to override the current working directory', () => { - expect(relative('../utils/index.css', '..')).toMatchInlineSnapshot(`"./utils/index.css"`) + expect(normalizeWindowsSeperators(relative('../utils/index.css', '..'))).toMatchInlineSnapshot( + `"./utils/index.css"`, + ) }) it('should be possible to always prefer the relative path', () => { expect( - relative('index.css', process.cwd(), { preferAbsoluteIfShorter: false }), + normalizeWindowsSeperators( + relative('index.css', process.cwd(), { preferAbsoluteIfShorter: false }), + ), ).toMatchInlineSnapshot(`"./index.css"`) }) }) diff --git a/packages/@tailwindcss-cli/src/utils/test-helpers.ts b/packages/@tailwindcss-cli/src/utils/test-helpers.ts new file mode 100644 index 000000000..8e61b0a13 --- /dev/null +++ b/packages/@tailwindcss-cli/src/utils/test-helpers.ts @@ -0,0 +1,5 @@ +import path from 'node:path' + +export function normalizeWindowsSeperators(p: string) { + return path.sep === '\\' ? p.replaceAll('\\', '/') : p +} diff --git a/packages/@tailwindcss-postcss/src/index.test.ts b/packages/@tailwindcss-postcss/src/index.test.ts index ffc2818e4..9e99944d0 100644 --- a/packages/@tailwindcss-postcss/src/index.test.ts +++ b/packages/@tailwindcss-postcss/src/index.test.ts @@ -41,7 +41,7 @@ test("`@import 'tailwindcss'` is replaced with the generated CSS", async () => { }) expect(result.messages).toContainEqual({ type: 'dir-dependency', - dir: expect.stringMatching(/example-project\/src$/g), + dir: expect.stringMatching(/example-project[\/|\\]src$/g), glob: expect.stringMatching(/^\*\*\/\*/g), parent: expect.any(String), plugin: expect.any(String), diff --git a/packages/tailwindcss/src/css-parser.bench.ts b/packages/tailwindcss/src/css-parser.bench.ts index 6bf059ad4..ab490e103 100644 --- a/packages/tailwindcss/src/css-parser.bench.ts +++ b/packages/tailwindcss/src/css-parser.bench.ts @@ -1,8 +1,10 @@ import { readFileSync } from 'node:fs' +import { fileURLToPath } from 'node:url' + import { bench } from 'vitest' import * as CSS from './css-parser.ts' -const currentFolder = new URL('..', import.meta.url).pathname +const currentFolder = fileURLToPath(new URL('..', import.meta.url)) const cssFile = readFileSync(currentFolder + './preflight.css', 'utf-8') bench('css-parser on preflight.css', () => {